From 7387b12cb9055f6ea348ebfe817c1274a099ddf0 Mon Sep 17 00:00:00 2001 From: Natalia Serrano Date: Tue, 25 Feb 2025 11:53:21 +0100 Subject: [PATCH] refs #1593 add python libs and executables --- client/functions/ogAddCmd | 25 + client/functions/ogAddRegistryKey | 24 + client/functions/ogAddRegistryValue | 25 + client/functions/ogCalculateChecksum | 32 + client/functions/ogCalculateFullChecksum | 32 + client/functions/ogChangeRepo | 23 + client/functions/ogCheckFs | 23 + client/functions/ogCheckIpAddress | 22 + client/functions/ogCleanLinuxDevices | 23 + client/functions/ogCleanOs | 23 + client/functions/ogConfigureFstab | 23 + client/functions/ogConfigureOgagent | 23 + client/functions/ogCopyEfiBootLoader | 23 + client/functions/ogCopyFile | 63 + client/functions/ogCreateCache | 36 + client/functions/ogCreateGptPartitions | 23 + client/functions/ogCreateImage | 37 + client/functions/ogCreateImageSyntax | 25 + client/functions/ogCreatePartitionTable | 30 + client/functions/ogCreatePartitions | 23 + client/functions/ogCreateTorrent | 31 + client/functions/ogDeleteCache | 13 + client/functions/ogDeleteFile | 32 + client/functions/ogDeletePartitionTable | 22 + client/functions/ogDeleteRegistryKey | 24 + client/functions/ogDeleteRegistryValue | 24 + client/functions/ogDeleteTree | 32 + client/functions/ogDevToDisk | 22 + client/functions/ogDiskToDev | 23 + client/functions/ogEcho | 24 + client/functions/ogExecAndLog | 53 + client/functions/ogExtendFs | 23 + client/functions/ogFindCache | 22 + client/functions/ogFixBootSector | 23 + client/functions/ogFormat | 28 + client/functions/ogFormatCache | 22 + client/functions/ogFormatFs | 25 + client/functions/ogGetArch | 22 + client/functions/ogGetCacheSize | 22 + client/functions/ogGetCacheSpace | 13 + client/functions/ogGetCaller | 22 + client/functions/ogGetDiskSize | 22 + client/functions/ogGetDiskType | 22 + client/functions/ogGetEsp | 22 + client/functions/ogGetFreeSize | 24 + client/functions/ogGetFsSize | 24 + client/functions/ogGetFsType | 23 + client/functions/ogGetHivePath | 23 + client/functions/ogGetHostname | 22 + client/functions/ogGetImageCompressor | 23 + client/functions/ogGetImageInfo | 22 + client/functions/ogGetImageProgram | 23 + client/functions/ogGetImageSize | 23 + client/functions/ogGetImageType | 23 + client/functions/ogGetIpAddress | 22 + client/functions/ogGetLastSector | 30 + client/functions/ogGetMacAddress | 22 + client/functions/ogGetMountPoint | 23 + client/functions/ogGetOsType | 23 + client/functions/ogGetOsUuid | 23 + client/functions/ogGetOsVersion | 23 + client/functions/ogGetParentPath | 32 + client/functions/ogGetPartitionActive | 22 + client/functions/ogGetPartitionId | 23 + client/functions/ogGetPartitionSize | 23 + client/functions/ogGetPartitionTableType | 22 + client/functions/ogGetPartitionType | 23 + client/functions/ogGetPartitionsNumber | 22 + client/functions/ogGetPath | 36 + client/functions/ogGetRegistryValue | 24 + client/functions/ogGetRepoIp | 22 + client/functions/ogGetSerialNumber | 17 + client/functions/ogGetServerIp | 22 + client/functions/ogGetSizeParameters | 21 + client/functions/ogGrubInstallMbr | 25 + client/functions/ogGrubInstallPartition | 25 + client/functions/ogHelp | 24 + client/functions/ogHidePartition | 23 + client/functions/ogIdToType | 22 + client/functions/ogInstallFirstBoot | 24 + client/functions/ogInstallMiniSetup | 35 + client/functions/ogInstallRunonce | 29 + client/functions/ogIsDiskLocked | 22 + client/functions/ogIsEfiActive | 22 + client/functions/ogIsFormated | 23 + client/functions/ogIsImageLocked | 23 + client/functions/ogIsLocked | 23 + client/functions/ogIsMounted | 23 + client/functions/ogIsPartitionLocked | 23 + client/functions/ogIsReadonly | 23 + client/functions/ogIsRepoLocked | 17 + client/functions/ogIsVirtualMachine | 22 + client/functions/ogIsWritable | 23 + client/functions/ogListHardwareInfo | 17 + client/functions/ogListLogicalPartitions | 22 + client/functions/ogListPartitions | 22 + client/functions/ogListPrimaryPartitions | 22 + client/functions/ogListRegistryKeys | 25 + client/functions/ogListRegistryValues | 25 + client/functions/ogListSoftware | 24 + client/functions/ogLock | 23 + client/functions/ogLockDisk | 22 + client/functions/ogLockImage | 30 + client/functions/ogLockPartition | 23 + client/functions/ogMakeDir | 32 + client/functions/ogMcastReceiverFile | 39 + client/functions/ogMcastReceiverPartition | 26 + client/functions/ogMcastSendFile | 46 + client/functions/ogMcastSendPartition | 26 + client/functions/ogMcastSyntax | 34 + client/functions/ogMount | 35 + client/functions/ogMountCache | 22 + client/functions/ogMountCdrom | 22 + client/functions/ogMountFirstFs | 22 + client/functions/ogMountFs | 23 + client/functions/ogNvramActiveEntry | 22 + client/functions/ogNvramAddEntry | 24 + client/functions/ogNvramDeleteEntry | 22 + client/functions/ogNvramGetCurrent | 22 + client/functions/ogNvramGetNext | 22 + client/functions/ogNvramGetOrder | 22 + client/functions/ogNvramGetTimeout | 22 + client/functions/ogNvramInactiveEntry | 22 + client/functions/ogNvramList | 22 + client/functions/ogNvramPxeFirstEntry | 22 + client/functions/ogNvramSetNext | 22 + client/functions/ogNvramSetOrder | 16 + client/functions/ogNvramSetTimeout | 22 + client/functions/ogRaiseError | 34 + client/functions/ogReduceFs | 23 + client/functions/ogRestoreEfiBootLoader | 23 + client/functions/ogRestoreImage | 25 + client/functions/ogRestoreImageSyntax | 25 + client/functions/ogSetPartitionActive | 23 + client/functions/ogSetPartitionId | 24 + client/functions/ogSetPartitionSize | 24 + client/functions/ogSetPartitionType | 24 + client/functions/ogSetRegistryValue | 25 + client/functions/ogSetWindowsName | 24 + client/functions/ogTorrentStart | 39 + client/functions/ogTypeToId | 23 + client/functions/ogUcastReceiverPartition | 26 + client/functions/ogUcastSendFile | 39 + client/functions/ogUcastSendPartition | 26 + client/functions/ogUcastSyntax | 34 + client/functions/ogUnhidePartition | 23 + client/functions/ogUninstallLinuxClient | 23 + client/functions/ogUninstallWindowsClient | 24 + client/functions/ogUnlock | 23 + client/functions/ogUnlockDisk | 22 + client/functions/ogUnlockImage | 30 + client/functions/ogUnlockPartition | 23 + client/functions/ogUnmount | 23 + client/functions/ogUnmountAll | 22 + client/functions/ogUnmountCache | 22 + client/functions/ogUnmountFs | 23 + client/functions/ogUnsetDirtyBit | 23 + client/functions/ogUpdateCacheIsNecesary | 24 + client/functions/ogUpdatePartitionTable | 13 + client/functions/ogWindowsBootParameters | 23 + client/functions/ogWindowsRegisterPartition | 26 + client/lib/python3/BootLib.py | 1018 +++++++++++++ client/lib/python3/CacheLib.py | 369 +++++ client/lib/python3/DiskLib.py | 1424 +++++++++++++++++++ client/lib/python3/FileLib.py | 517 +++++++ client/lib/python3/FileSystemLib.py | 906 ++++++++++++ client/lib/python3/ImageLib.py | 839 +++++++++++ client/lib/python3/InventoryLib.py | 531 +++++++ client/lib/python3/NetLib.py | 315 ++++ client/lib/python3/PostConfLib.py | 320 +++++ client/lib/python3/ProtocolLib.py | 973 +++++++++++++ client/lib/python3/RegistryLib.py | 382 +++++ client/lib/python3/StringLib.py | 31 + client/lib/python3/SystemLib.py | 310 ++++ client/lib/python3/ogGlobals.py | 145 ++ 175 files changed, 12074 insertions(+) create mode 100755 client/functions/ogAddCmd create mode 100755 client/functions/ogAddRegistryKey create mode 100755 client/functions/ogAddRegistryValue create mode 100755 client/functions/ogCalculateChecksum create mode 100755 client/functions/ogCalculateFullChecksum create mode 100755 client/functions/ogChangeRepo create mode 100755 client/functions/ogCheckFs create mode 100755 client/functions/ogCheckIpAddress create mode 100755 client/functions/ogCleanLinuxDevices create mode 100755 client/functions/ogCleanOs create mode 100755 client/functions/ogConfigureFstab create mode 100755 client/functions/ogConfigureOgagent create mode 100755 client/functions/ogCopyEfiBootLoader create mode 100755 client/functions/ogCopyFile create mode 100755 client/functions/ogCreateCache create mode 100755 client/functions/ogCreateGptPartitions create mode 100755 client/functions/ogCreateImage create mode 100755 client/functions/ogCreateImageSyntax create mode 100755 client/functions/ogCreatePartitionTable create mode 100755 client/functions/ogCreatePartitions create mode 100755 client/functions/ogCreateTorrent create mode 100755 client/functions/ogDeleteCache create mode 100755 client/functions/ogDeleteFile create mode 100755 client/functions/ogDeletePartitionTable create mode 100755 client/functions/ogDeleteRegistryKey create mode 100755 client/functions/ogDeleteRegistryValue create mode 100755 client/functions/ogDeleteTree create mode 100755 client/functions/ogDevToDisk create mode 100755 client/functions/ogDiskToDev create mode 100755 client/functions/ogEcho create mode 100755 client/functions/ogExecAndLog create mode 100755 client/functions/ogExtendFs create mode 100755 client/functions/ogFindCache create mode 100755 client/functions/ogFixBootSector create mode 100755 client/functions/ogFormat create mode 100755 client/functions/ogFormatCache create mode 100755 client/functions/ogFormatFs create mode 100755 client/functions/ogGetArch create mode 100755 client/functions/ogGetCacheSize create mode 100755 client/functions/ogGetCacheSpace create mode 100755 client/functions/ogGetCaller create mode 100755 client/functions/ogGetDiskSize create mode 100755 client/functions/ogGetDiskType create mode 100755 client/functions/ogGetEsp create mode 100755 client/functions/ogGetFreeSize create mode 100755 client/functions/ogGetFsSize create mode 100755 client/functions/ogGetFsType create mode 100755 client/functions/ogGetHivePath create mode 100755 client/functions/ogGetHostname create mode 100755 client/functions/ogGetImageCompressor create mode 100755 client/functions/ogGetImageInfo create mode 100755 client/functions/ogGetImageProgram create mode 100755 client/functions/ogGetImageSize create mode 100755 client/functions/ogGetImageType create mode 100755 client/functions/ogGetIpAddress create mode 100755 client/functions/ogGetLastSector create mode 100755 client/functions/ogGetMacAddress create mode 100755 client/functions/ogGetMountPoint create mode 100755 client/functions/ogGetOsType create mode 100755 client/functions/ogGetOsUuid create mode 100755 client/functions/ogGetOsVersion create mode 100755 client/functions/ogGetParentPath create mode 100755 client/functions/ogGetPartitionActive create mode 100755 client/functions/ogGetPartitionId create mode 100755 client/functions/ogGetPartitionSize create mode 100755 client/functions/ogGetPartitionTableType create mode 100755 client/functions/ogGetPartitionType create mode 100755 client/functions/ogGetPartitionsNumber create mode 100755 client/functions/ogGetPath create mode 100755 client/functions/ogGetRegistryValue create mode 100755 client/functions/ogGetRepoIp create mode 100755 client/functions/ogGetSerialNumber create mode 100755 client/functions/ogGetServerIp create mode 100755 client/functions/ogGetSizeParameters create mode 100755 client/functions/ogGrubInstallMbr create mode 100755 client/functions/ogGrubInstallPartition create mode 100755 client/functions/ogHelp create mode 100755 client/functions/ogHidePartition create mode 100755 client/functions/ogIdToType create mode 100755 client/functions/ogInstallFirstBoot create mode 100755 client/functions/ogInstallMiniSetup create mode 100755 client/functions/ogInstallRunonce create mode 100755 client/functions/ogIsDiskLocked create mode 100755 client/functions/ogIsEfiActive create mode 100755 client/functions/ogIsFormated create mode 100755 client/functions/ogIsImageLocked create mode 100755 client/functions/ogIsLocked create mode 100755 client/functions/ogIsMounted create mode 100755 client/functions/ogIsPartitionLocked create mode 100755 client/functions/ogIsReadonly create mode 100755 client/functions/ogIsRepoLocked create mode 100755 client/functions/ogIsVirtualMachine create mode 100755 client/functions/ogIsWritable create mode 100755 client/functions/ogListHardwareInfo create mode 100755 client/functions/ogListLogicalPartitions create mode 100755 client/functions/ogListPartitions create mode 100755 client/functions/ogListPrimaryPartitions create mode 100755 client/functions/ogListRegistryKeys create mode 100755 client/functions/ogListRegistryValues create mode 100755 client/functions/ogListSoftware create mode 100755 client/functions/ogLock create mode 100755 client/functions/ogLockDisk create mode 100755 client/functions/ogLockImage create mode 100755 client/functions/ogLockPartition create mode 100755 client/functions/ogMakeDir create mode 100755 client/functions/ogMcastReceiverFile create mode 100755 client/functions/ogMcastReceiverPartition create mode 100755 client/functions/ogMcastSendFile create mode 100755 client/functions/ogMcastSendPartition create mode 100755 client/functions/ogMcastSyntax create mode 100755 client/functions/ogMount create mode 100755 client/functions/ogMountCache create mode 100755 client/functions/ogMountCdrom create mode 100755 client/functions/ogMountFirstFs create mode 100755 client/functions/ogMountFs create mode 100755 client/functions/ogNvramActiveEntry create mode 100755 client/functions/ogNvramAddEntry create mode 100755 client/functions/ogNvramDeleteEntry create mode 100755 client/functions/ogNvramGetCurrent create mode 100755 client/functions/ogNvramGetNext create mode 100755 client/functions/ogNvramGetOrder create mode 100755 client/functions/ogNvramGetTimeout create mode 100755 client/functions/ogNvramInactiveEntry create mode 100755 client/functions/ogNvramList create mode 100755 client/functions/ogNvramPxeFirstEntry create mode 100755 client/functions/ogNvramSetNext create mode 100755 client/functions/ogNvramSetOrder create mode 100755 client/functions/ogNvramSetTimeout create mode 100755 client/functions/ogRaiseError create mode 100755 client/functions/ogReduceFs create mode 100755 client/functions/ogRestoreEfiBootLoader create mode 100755 client/functions/ogRestoreImage create mode 100755 client/functions/ogRestoreImageSyntax create mode 100755 client/functions/ogSetPartitionActive create mode 100755 client/functions/ogSetPartitionId create mode 100755 client/functions/ogSetPartitionSize create mode 100755 client/functions/ogSetPartitionType create mode 100755 client/functions/ogSetRegistryValue create mode 100755 client/functions/ogSetWindowsName create mode 100755 client/functions/ogTorrentStart create mode 100755 client/functions/ogTypeToId create mode 100755 client/functions/ogUcastReceiverPartition create mode 100755 client/functions/ogUcastSendFile create mode 100755 client/functions/ogUcastSendPartition create mode 100755 client/functions/ogUcastSyntax create mode 100755 client/functions/ogUnhidePartition create mode 100755 client/functions/ogUninstallLinuxClient create mode 100755 client/functions/ogUninstallWindowsClient create mode 100755 client/functions/ogUnlock create mode 100755 client/functions/ogUnlockDisk create mode 100755 client/functions/ogUnlockImage create mode 100755 client/functions/ogUnlockPartition create mode 100755 client/functions/ogUnmount create mode 100755 client/functions/ogUnmountAll create mode 100755 client/functions/ogUnmountCache create mode 100755 client/functions/ogUnmountFs create mode 100755 client/functions/ogUnsetDirtyBit create mode 100755 client/functions/ogUpdateCacheIsNecesary create mode 100755 client/functions/ogUpdatePartitionTable create mode 100755 client/functions/ogWindowsBootParameters create mode 100755 client/functions/ogWindowsRegisterPartition create mode 100644 client/lib/python3/BootLib.py create mode 100644 client/lib/python3/CacheLib.py create mode 100644 client/lib/python3/DiskLib.py create mode 100644 client/lib/python3/FileLib.py create mode 100644 client/lib/python3/FileSystemLib.py create mode 100644 client/lib/python3/ImageLib.py create mode 100644 client/lib/python3/InventoryLib.py create mode 100644 client/lib/python3/NetLib.py create mode 100644 client/lib/python3/PostConfLib.py create mode 100644 client/lib/python3/ProtocolLib.py create mode 100644 client/lib/python3/RegistryLib.py create mode 100644 client/lib/python3/StringLib.py create mode 100644 client/lib/python3/SystemLib.py create mode 100644 client/lib/python3/ogGlobals.py diff --git a/client/functions/ogAddCmd b/client/functions/ogAddCmd new file mode 100755 index 0000000..8c0b913 --- /dev/null +++ b/client/functions/ogAddCmd @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from PostConfLib import ogAddCmd + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('cmdfile') +parser.add_argument ('cmd') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogAddCmd', 'ogAddCmd int_ndisk int_npartition str_filename str_commands', ['ogAddCmd 1 1 filename.cmd command']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogAddCmd (args.disk, args.par, args.cmdfile, args.cmd) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogAddRegistryKey b/client/functions/ogAddRegistryKey new file mode 100755 index 0000000..8b0c59b --- /dev/null +++ b/client/functions/ogAddRegistryKey @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from RegistryLib import ogAddRegistryKey + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('mntpt') +parser.add_argument ('hive') +parser.add_argument ('k') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogAddRegistryKey', 'ogAddRegistryKey path_mountpoint str_hive str_key', [r'ogAddRegistryKey /mnt/sda1 SOFTWARE "\Microsoft\NewKey"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogAddRegistryKey (args.mntpt, args.hive, args.k) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogAddRegistryValue b/client/functions/ogAddRegistryValue new file mode 100755 index 0000000..d4dd054 --- /dev/null +++ b/client/functions/ogAddRegistryValue @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from RegistryLib import ogAddRegistryValue + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('mntpt') +parser.add_argument ('hive') +parser.add_argument ('k') +parser.add_argument ('vtype', nargs='?', default='STRING') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogAddRegistryValue', 'ogAddRegistryValue path_mountpoint str_hive str_valuename [str_valuetype]', [r'ogAddRegistryValue /mnt/sda1 SOFTWARE "\Microsoft\NewKey\Value1"', r'ogAddRegistryValue /mnt/sda1 SOFTWARE "\Microsoft\NewKey\Value1" DWORD']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogAddRegistryValue (args.mntpt, args.hive, args.k, args.vtype) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCalculateChecksum b/client/functions/ogCalculateChecksum new file mode 100755 index 0000000..d55da2e --- /dev/null +++ b/client/functions/ogCalculateChecksum @@ -0,0 +1,32 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileLib import ogCalculateChecksum + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCalculateChecksum', 'ogCalculateChecksum [ str_repo | int_ndisk int_npartition ] path_filepath', ['ogCalculateChecksum REPO ubuntu.img']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('container', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) +elif 4 == len (sys.argv): + parser.add_argument ('disk', nargs='?', default=None) + parser.add_argument ('par', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + +args = parser.parse_args() + +if 3 == len (sys.argv): + ret = ogCalculateChecksum (container=args.container, file=args.file) +elif 4 == len (sys.argv): + ret = ogCalculateChecksum (container=f'{args.disk} {args.par}', file=args.file) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCalculateFullChecksum b/client/functions/ogCalculateFullChecksum new file mode 100755 index 0000000..f871f03 --- /dev/null +++ b/client/functions/ogCalculateFullChecksum @@ -0,0 +1,32 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileLib import ogCalculateFullChecksum + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCalculateFullChecksum', 'ogCalculateFullChecksum [ str_repo | int_ndisk int_npartition ] path_filepath', ['ogCalculateFullChecksum REPO ubuntu.img']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('container', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) +elif 4 == len (sys.argv): + parser.add_argument ('disk', nargs='?', default=None) + parser.add_argument ('par', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + +args = parser.parse_args() + +if 3 == len (sys.argv): + ret = ogCalculateFullChecksum (container=args.container, file=args.file) +elif 4 == len (sys.argv): + ret = ogCalculateFullChecksum (container=f'{args.disk} {args.par}', file=args.file) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogChangeRepo b/client/functions/ogChangeRepo new file mode 100755 index 0000000..0a65304 --- /dev/null +++ b/client/functions/ogChangeRepo @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from NetLib import ogChangeRepo + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('ip_repo') +parser.add_argument ('og_unit', nargs='?', default=None) + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogChangeRepo', 'ogChangeRepo IPREPO', ['ogChangeRepo 10.1.120.3']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogChangeRepo (args.ip_repo, args.og_unit) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCheckFs b/client/functions/ogCheckFs new file mode 100755 index 0000000..7eade6a --- /dev/null +++ b/client/functions/ogCheckFs @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogCheckFs + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCheckFs', 'ogCheckFs int_ndisk int_nfilesys', ['ogCheckFs 1 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogCheckFs (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCheckIpAddress b/client/functions/ogCheckIpAddress new file mode 100755 index 0000000..0e25310 --- /dev/null +++ b/client/functions/ogCheckIpAddress @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from StringLib import ogCheckIpAddress + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('ip') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCheckIpAddress') + sys.exit (0) + +args = parser.parse_args() + +ret = ogCheckIpAddress (args.ip) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCleanLinuxDevices b/client/functions/ogCleanLinuxDevices new file mode 100755 index 0000000..7603084 --- /dev/null +++ b/client/functions/ogCleanLinuxDevices @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogCleanLinuxDevices + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCleanLinuxDevices', 'ogCleanLinuxDevices int_ndisk int_nfilesys', ['ogCleanLinuxDevices 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogCleanLinuxDevices (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCleanOs b/client/functions/ogCleanOs new file mode 100755 index 0000000..e2309c6 --- /dev/null +++ b/client/functions/ogCleanOs @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from PostConfLib import ogCleanOs + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCleanOs', 'ogCleanOs int_ndisk int_nfilesys', ['ogCleanOs 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogCleanOs (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogConfigureFstab b/client/functions/ogConfigureFstab new file mode 100755 index 0000000..03d351d --- /dev/null +++ b/client/functions/ogConfigureFstab @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogConfigureFstab + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogConfigureFstab', 'ogConfigureFstab int_ndisk int_nfilesys', ['ogConfigureFstab 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogConfigureFstab (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogConfigureOgagent b/client/functions/ogConfigureOgagent new file mode 100755 index 0000000..7ed9fcd --- /dev/null +++ b/client/functions/ogConfigureOgagent @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from PostConfLib import ogConfigureOgagent + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogConfigureOgagent', 'ogConfigureOgagent int_ndisk int_filesys', ['ogConfigureOgagent 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogConfigureOgagent (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCopyEfiBootLoader b/client/functions/ogCopyEfiBootLoader new file mode 100755 index 0000000..41d5d9b --- /dev/null +++ b/client/functions/ogCopyEfiBootLoader @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogCopyEfiBootLoader + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCopyEfiBootLoader', 'ogCopyEfiBootLoader int_ndisk int_part', ['ogCopyEfiBootLoader 1 2']) + sys.exit (0) + +args = parser.parse_args() +ret = ogCopyEfiBootLoader (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCopyFile b/client/functions/ogCopyFile new file mode 100755 index 0000000..04f1784 --- /dev/null +++ b/client/functions/ogCopyFile @@ -0,0 +1,63 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileLib import ogCopyFile + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCopyFile', 'ogCopyFile [ str_repo | int_ndisk int_npartition ] path_source [ str_repo | int_ndisk int_npartition ] path_target', ['ogCopyFile REPO newfile.txt 1 2 /tmp/newfile.txt']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 5 == len (sys.argv): + parser.add_argument ('src_container') + parser.add_argument ('src_file') + parser.add_argument ('dst_container') + parser.add_argument ('dst_file') + args = parser.parse_args() + src = { 'container': args.src_container, 'file': args.src_file } + dst = { 'container': args.dst_container, 'file': args.dst_file } +elif 7 == len (sys.argv): + parser.add_argument ('src_disk') + parser.add_argument ('src_par') + parser.add_argument ('src_file') + parser.add_argument ('dst_disk') + parser.add_argument ('dst_par') + parser.add_argument ('dst_file') + args = parser.parse_args() + src = { 'disk': args.src_disk, 'par': args.src_par, 'file': args.src_file } + dst = { 'disk': args.dst_disk, 'par': args.dst_par, 'file': args.dst_file } +elif 6 == len (sys.argv): + ## can be either: + ## - src_disk src_par src_file dst_container dst_file + ## - src_container src_file dst_disk dst_par dst_file + + try: + num = int (sys.argv[1]) ## raises ValueError if sys.argv[1] doesn't look like a number + ## "src_disk src_par src_file dst_container dst_file" + parser.add_argument ('src_disk') + parser.add_argument ('src_par') + parser.add_argument ('src_file') + parser.add_argument ('dst_container') + parser.add_argument ('dst_file') + args = parser.parse_args() + src = { 'disk': args.src_disk, 'par': args.src_par, 'file': args.src_file } + dst = { 'container': args.dst_container, 'file': args.dst_file } + except: + ## "src_container src_file dst_disk dst_par dst_file" + parser.add_argument ('src_container') + parser.add_argument ('src_file') + parser.add_argument ('dst_disk') + parser.add_argument ('dst_par') + parser.add_argument ('dst_file') + args = parser.parse_args() + src = { 'container': args.src_container, 'file': args.src_file } + dst = { 'disk': args.dst_disk, 'par': args.dst_par, 'file': args.dst_file } + +ret = ogCopyFile (src, dst) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCreateCache b/client/functions/ogCreateCache new file mode 100755 index 0000000..62a97e5 --- /dev/null +++ b/client/functions/ogCreateCache @@ -0,0 +1,36 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from CacheLib import ogCreateCache + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCreateCache', 'ogCreateCache [int_ndisk [int_npart]] int_partsize', ['ogCreateCache 10000000', 'ogCreateCache 1 10000000', 'ogCreateCache 1 4 10000000']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 2 == len (sys.argv): + parser.add_argument ('sizecache') +elif 3 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('sizecache') +elif 4 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('part') + parser.add_argument ('sizecache') + +args = parser.parse_args() + +if 2 == len (sys.argv): + ret = ogCreateCache (sizecache=args.sizecache) +elif 3 == len (sys.argv): + ret = ogCreateCache (ndsk=args.disk, sizecache=args.sizecache) +elif 4 == len (sys.argv): + ret = ogCreateCache (ndsk=int(args.disk), part=int(args.part), sizecache=int(args.sizecache)) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCreateGptPartitions b/client/functions/ogCreateGptPartitions new file mode 100755 index 0000000..0259325 --- /dev/null +++ b/client/functions/ogCreateGptPartitions @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogCreateGptPartitions + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCreateGptPartitions', 'ogCreateGptPartitions int_ndisk str_parttype:int_partsize ...', ['ogCreateGptPartitions 1 NTFS:10000000 EXT3:5000000 LINUX-SWAP:1000000']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('parts', nargs='+') +args = parser.parse_args() + +ret = ogCreateGptPartitions (args.disk, args.parts) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCreateImage b/client/functions/ogCreateImage new file mode 100755 index 0000000..14c9709 --- /dev/null +++ b/client/functions/ogCreateImage @@ -0,0 +1,37 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogCreateImage + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCreateImage', 'ogCreateImage int_ndisk int_npart str_repo path_image', ['ogCreateImage 1 1 REPO /aula1/win7']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 5 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') + parser.add_argument ('container') + parser.add_argument ('imgfile') +elif 7 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') + parser.add_argument ('container') + parser.add_argument ('imgfile') + parser.add_argument ('tool') + parser.add_argument ('level') + +args = parser.parse_args() + +if 5 == len (sys.argv): + ret = ogCreateImage (args.disk, args.par, args.container, args.imgfile) +elif 7 == len (sys.argv): + ret = ogCreateImage (args.disk, args.par, args.container, args.imgfile, args.tool, args.level) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCreateImageSyntax b/client/functions/ogCreateImageSyntax new file mode 100755 index 0000000..bc3651b --- /dev/null +++ b/client/functions/ogCreateImageSyntax @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogCreateImageSyntax + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('dev') +parser.add_argument ('imgfile') +parser.add_argument ('tool', nargs='?', default='partclone') +parser.add_argument ('level', nargs='?', default='gzip') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCreateImageSyntax', 'ogCreateImageSyntax path_device path_imagefile [str_tool] [str_compressionlevel]', ['ogCreateImageSyntax /dev/sda1 /opt/opengnsys/images/prueba.img partclone lzop', 'ogCreateImageSyntax /dev/sda1 /opt/opengnsys/images/prueba.img']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogCreateImageSyntax (args.dev, args.imgfile, args.tool, args.level) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCreatePartitionTable b/client/functions/ogCreatePartitionTable new file mode 100755 index 0000000..415c10c --- /dev/null +++ b/client/functions/ogCreatePartitionTable @@ -0,0 +1,30 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogCreatePartitionTable + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCreatePartitionTable', 'ogCreatePartitionTable int_ndisk [str_partype]', ['ogCreatePartitionTable 1 GPT', 'ogCreatePartitionTable 1']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 2 == len (sys.argv): + parser.add_argument ('disk') +elif 3 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('createptt') + +args = parser.parse_args() + +if 2 == len (sys.argv): + ret = ogCreatePartitionTable (args.disk) +elif 3 == len (sys.argv): + ret = ogCreatePartitionTable (args.disk, args.createptt) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCreatePartitions b/client/functions/ogCreatePartitions new file mode 100755 index 0000000..8269a53 --- /dev/null +++ b/client/functions/ogCreatePartitions @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogCreatePartitions + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCreatePartitions', 'ogCreatePartitions int_ndisk str_parttype:int_partsize ...', ['ogCreatePartitions 1 NTFS:10000000 EXT3:5000000 LINUX-SWAP:1000000']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('parts', nargs='+') +args = parser.parse_args() + +ret = ogCreatePartitions (args.disk, args.parts) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogCreateTorrent b/client/functions/ogCreateTorrent new file mode 100755 index 0000000..409bd31 --- /dev/null +++ b/client/functions/ogCreateTorrent @@ -0,0 +1,31 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogCreateTorrent + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogCreateTorrent', 'ogCreateTorrent [str_REPOSITORY] [int_ndisk int_npart] Relative_path_file IpBttrack', ['ogCreateTorrent 1 1 /aula1/winxp 10.1.15.23', 'ogCreateTorrent REPO /aula1/winxp 10.1.15.45']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 4 == len (sys.argv): + parser.add_argument ('container') +elif 5 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') + +parser.add_argument ('file') +parser.add_argument ('ip_bttrack') +args = parser.parse_args() + +if 4 == len (sys.argv): + ret = ogCreateTorrent (container=args.container, file=args.file, ip_bttrack=args.ip_bttrack) +elif 5 == len (sys.argv): + ret = ogCreateTorrent (disk=args.disk, par=args.par, file=args.file, ip_bttrack=args.ip_bttrack) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogDeleteCache b/client/functions/ogDeleteCache new file mode 100755 index 0000000..80914b8 --- /dev/null +++ b/client/functions/ogDeleteCache @@ -0,0 +1,13 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from CacheLib import ogDeleteCache + +ret = ogDeleteCache() + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogDeleteFile b/client/functions/ogDeleteFile new file mode 100755 index 0000000..32d4763 --- /dev/null +++ b/client/functions/ogDeleteFile @@ -0,0 +1,32 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileLib import ogDeleteFile + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogDeleteFile', 'ogDeleteFile [ str_repo | int_ndisk int_npartition ] path_file', ['ogDeleteFile 1 2 /tmp/newfile.txt']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('container', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) +elif 4 == len (sys.argv): + parser.add_argument ('disk', nargs='?', default=None) + parser.add_argument ('par', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + +args = parser.parse_args() + +if 3 == len (sys.argv): + ret = ogDeleteFile (container=args.container, file=args.file) +elif 4 == len (sys.argv): + ret = ogDeleteFile (container=f'{args.disk} {args.par}', file=args.file) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogDeletePartitionTable b/client/functions/ogDeletePartitionTable new file mode 100755 index 0000000..5d35b5d --- /dev/null +++ b/client/functions/ogDeletePartitionTable @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogDeletePartitionTable + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogDeletePartitionTable', 'ogDeletePartitionTable int_ndisk', ['ogDeletePartitionTable 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogDeletePartitionTable (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogDeleteRegistryKey b/client/functions/ogDeleteRegistryKey new file mode 100755 index 0000000..3eba2e1 --- /dev/null +++ b/client/functions/ogDeleteRegistryKey @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from RegistryLib import ogDeleteRegistryKey + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('mntpt') +parser.add_argument ('hive') +parser.add_argument ('k') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogDeleteRegistryKey', 'ogDeleteRegistryKey path_mountpoint str_hive str_key', [r'ogDeleteRegistryKey /mnt/sda1 SOFTWARE "\Microsoft\NewKey"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogDeleteRegistryKey (args.mntpt, args.hive, args.k) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogDeleteRegistryValue b/client/functions/ogDeleteRegistryValue new file mode 100755 index 0000000..7721bfa --- /dev/null +++ b/client/functions/ogDeleteRegistryValue @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from RegistryLib import ogDeleteRegistryValue + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('mntpt') +parser.add_argument ('hive') +parser.add_argument ('k') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogDeleteRegistryValue', 'ogDeleteRegistryValue path_mountpoint str_hive str_valuename', [r'ogDeleteRegistryValue /mnt/sda1 SOFTWARE "\Microsoft\NewKey\Value1"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogDeleteRegistryValue (args.mntpt, args.hive, args.k) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogDeleteTree b/client/functions/ogDeleteTree new file mode 100755 index 0000000..527b1a5 --- /dev/null +++ b/client/functions/ogDeleteTree @@ -0,0 +1,32 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileLib import ogDeleteTree + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogDeleteTree', 'ogDeleteTree [ str_repo | int_ndisk int_npartition ] path_dir', ['ogDeleteTree 1 2 /tmp/newdir']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('container', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) +elif 4 == len (sys.argv): + parser.add_argument ('disk', nargs='?', default=None) + parser.add_argument ('par', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + +args = parser.parse_args() + +if 3 == len (sys.argv): + ret = ogDeleteTree (container=args.container, file=args.file) +elif 4 == len (sys.argv): + ret = ogDeleteTree (container=f'{args.disk} {args.par}', file=args.file) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogDevToDisk b/client/functions/ogDevToDisk new file mode 100755 index 0000000..b3d6fea --- /dev/null +++ b/client/functions/ogDevToDisk @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogDevToDisk + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('arg_dev') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogDevToDisk', 'ogDevToDisk path_device | LABEL=str_label | UUID=str_uuid', ['ogDevToDisk /dev/sda', 'ogDevToDisk /dev/sda1', 'ogDevToDisk LABEL=CACHE']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogDevToDisk (args.arg_dev) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogDiskToDev b/client/functions/ogDiskToDev new file mode 100755 index 0000000..d12736d --- /dev/null +++ b/client/functions/ogDiskToDev @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogDiskToDev + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('arg_disk', nargs='?', default=None) +parser.add_argument ('arg_part', nargs='?', default=None) + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogDiskToDev', 'ogDiskToDev int_ndisk [int_npartition]', ['ogDiskToDev', 'ogDiskToDev 1', 'ogDiskToDev 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogDiskToDev (args.arg_disk, args.arg_part) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogEcho b/client/functions/ogEcho new file mode 100755 index 0000000..14d8bf5 --- /dev/null +++ b/client/functions/ogEcho @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from SystemLib import ogEcho + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('logtypes') +parser.add_argument ('loglevel') +parser.add_argument ('msg') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogEcho') + sys.exit (0) + +args = parser.parse_args() + +ret = ogEcho (args.logtypes, args.loglevel, args.msg) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogExecAndLog b/client/functions/ogExecAndLog new file mode 100755 index 0000000..977f6b4 --- /dev/null +++ b/client/functions/ogExecAndLog @@ -0,0 +1,53 @@ +#!/usr/bin/python3 + +import sys +## lo siento, pero tiene que ser así +from BootLib import * +from CacheLib import * +from DiskLib import * +from FileLib import * +from FileSystemLib import * +from ImageLib import * +from InventoryLib import * +from NetLib import * +from PostConfLib import * +from ProtocolLib import * +from RegistryLib import * +from StringLib import * +from SystemLib import * +from UEFILib import * + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogExecAndLog', 'ogExecAndLog str_logfile ... str_command ...', ['ogExecAndLog COMMAND ls -al /']) + sys.exit (0) + +logtypes = [] +while True: + if sys.argv[1] in ['command', 'log', 'session']: + logtypes.append (sys.argv.pop (1)) + else: break + +fun_name = sys.argv.pop (1) +try: + fun = locals()[fun_name] +except KeyError: + print (f'not implemented: {fun_name}') + sys.exit (1) + +args = [] +kwargs = {} +for arg in sys.argv[1:]: + if '=' in arg: + k, v = arg.split ('=') + kwargs[k] = v + else: + args.append (arg) + +## args has to be a tuple +args = tuple (args) + +ret = ogExecAndLog (logtypes, fun, *args, **kwargs) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) diff --git a/client/functions/ogExtendFs b/client/functions/ogExtendFs new file mode 100755 index 0000000..b706e87 --- /dev/null +++ b/client/functions/ogExtendFs @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogExtendFs + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogExtendFs', 'ogExtendFs int_ndisk int_nfilesys', ['ogExtendFs 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogExtendFs (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogFindCache b/client/functions/ogFindCache new file mode 100755 index 0000000..181872d --- /dev/null +++ b/client/functions/ogFindCache @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from CacheLib import ogFindCache + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogFindCache', 'ogFindCache') + sys.exit (0) + +args = parser.parse_args() + +ret = ogFindCache () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogFixBootSector b/client/functions/ogFixBootSector new file mode 100755 index 0000000..3e9ecb5 --- /dev/null +++ b/client/functions/ogFixBootSector @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogFixBootSector + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogFixBootSector', 'ogFixBootSector int_ndisk int_partition', ['ogFixBootSector 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogFixBootSector (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogFormat b/client/functions/ogFormat new file mode 100755 index 0000000..cc955a2 --- /dev/null +++ b/client/functions/ogFormat @@ -0,0 +1,28 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogFormat +from CacheLib import ogFormatCache + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogFormat', 'ogFormat int_ndisk int_nfilesys [str_label]', ['ogFormat 1 1', 'ogFormat 1 1 EXT4', 'ogFormat 1 1 DATA', 'ogFormat 1 1 EXT4 DATA']) + sys.exit (0) + +if 2 == len (sys.argv) and 'cache' == sys.argv[1]: + ret = ogFormatCache() +else: + parser = argparse.ArgumentParser (add_help=False) + parser.add_argument ('disk') + parser.add_argument ('par') + parser.add_argument ('fs', nargs='?', default=None) + parser.add_argument ('label', nargs='?', default=None) + args = parser.parse_args() + ret = ogFormat (args.disk, args.par, args.fs, args.label) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogFormatCache b/client/functions/ogFormatCache new file mode 100755 index 0000000..375d8b2 --- /dev/null +++ b/client/functions/ogFormatCache @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from CacheLib import ogFormatCache + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogFormatCache', 'ogFormatCache') + sys.exit (0) + +args = parser.parse_args() + +ret = ogFormatCache () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogFormatFs b/client/functions/ogFormatFs new file mode 100755 index 0000000..babe6ef --- /dev/null +++ b/client/functions/ogFormatFs @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogFormatFs + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('type', nargs='?', default=None) +parser.add_argument ('label', nargs='?', default=None) + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogFormatFs', 'ogFormatFs int_ndisk int_nfilesys [str_label]', ['ogFormatFs 1 1', 'ogFormatFs 1 1 EXT4', 'ogFormatFs 1 1 DATA', 'ogFormatFs 1 1 EXT4 DATA']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogFormatFs (args.disk, args.par, args.type, args.label) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetArch b/client/functions/ogGetArch new file mode 100755 index 0000000..bf24319 --- /dev/null +++ b/client/functions/ogGetArch @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from InventoryLib import ogGetArch + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetArch') + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetArch () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetCacheSize b/client/functions/ogGetCacheSize new file mode 100755 index 0000000..51a73dc --- /dev/null +++ b/client/functions/ogGetCacheSize @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from CacheLib import ogGetCacheSize + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetCacheSize', 'ogGetCacheSize') + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetCacheSize () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetCacheSpace b/client/functions/ogGetCacheSpace new file mode 100755 index 0000000..2e5dce3 --- /dev/null +++ b/client/functions/ogGetCacheSpace @@ -0,0 +1,13 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from CacheLib import ogGetCacheSpace + +ret = ogGetCacheSpace() + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetCaller b/client/functions/ogGetCaller new file mode 100755 index 0000000..2147fb2 --- /dev/null +++ b/client/functions/ogGetCaller @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from SystemLib import ogGetCaller + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetCaller') + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetCaller () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetDiskSize b/client/functions/ogGetDiskSize new file mode 100755 index 0000000..ea7c42e --- /dev/null +++ b/client/functions/ogGetDiskSize @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogGetDiskSize + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetDiskSize', 'ogGetDiskSize int_ndisk', ['ogGetDiskSize 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGetDiskSize (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetDiskType b/client/functions/ogGetDiskType new file mode 100755 index 0000000..022482f --- /dev/null +++ b/client/functions/ogGetDiskType @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogGetDiskType + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('dev') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetDiskType', 'ogGetDiskType path_device', ['ogGetDiskType /dev/sdb']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGetDiskType (args.dev) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetEsp b/client/functions/ogGetEsp new file mode 100755 index 0000000..3431956 --- /dev/null +++ b/client/functions/ogGetEsp @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogGetEsp + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetEsp') + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetEsp () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetFreeSize b/client/functions/ogGetFreeSize new file mode 100755 index 0000000..5f1899e --- /dev/null +++ b/client/functions/ogGetFreeSize @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogGetFreeSize + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('part') +parser.add_argument ('unit', nargs='?', default='KB') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetFreeSize', 'ogGetFreeSize int_disco int_partition str_SizeOutput [ kB MB GB ]', ['ogGetFreeSize 1 1 MB']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetFreeSize (args.disk, args.part, args.unit) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetFsSize b/client/functions/ogGetFsSize new file mode 100755 index 0000000..9227810 --- /dev/null +++ b/client/functions/ogGetFsSize @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogGetFsSize + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('unit', nargs='?', default='KB') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetFsSize', 'ogGetFsSize int_ndisk int_npartition [str_unit]', ['ogGetFsSize 1 1', 'ogGetFsSize 1 1 KB']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetFsSize (args.disk, args.par, args.unit) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetFsType b/client/functions/ogGetFsType new file mode 100755 index 0000000..d89b09f --- /dev/null +++ b/client/functions/ogGetFsType @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogGetFsType + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('part') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetFsType', 'ogGetFsType int_ndisk int_nfilesys', ['ogGetFsType 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetFsType (args.disk, args.part) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetHivePath b/client/functions/ogGetHivePath new file mode 100755 index 0000000..ebac741 --- /dev/null +++ b/client/functions/ogGetHivePath @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from RegistryLib import ogGetHivePath + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('mntpt') +parser.add_argument ('hive') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetHivePath', 'ogGetHivePath path_mountpoint [str_hive|str_user]', ['ogGetHivePath /mnt/sda1 SOFTWARE', 'ogGetHivePath /mnt/sda1 user1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetHivePath (args.mntpt, args.hive) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetHostname b/client/functions/ogGetHostname new file mode 100755 index 0000000..d042a3c --- /dev/null +++ b/client/functions/ogGetHostname @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from NetLib import ogGetHostname + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetHostname') + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetHostname () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetImageCompressor b/client/functions/ogGetImageCompressor new file mode 100755 index 0000000..7b21fb3 --- /dev/null +++ b/client/functions/ogGetImageCompressor @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogGetImageCompressor + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('container') +parser.add_argument ('filename') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetImageCompressor', 'ogGetImageCompressor str_repo path_image', ['ogGetImageCompressor REPO prueba']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetImageCompressor (args.container, args.filename) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetImageInfo b/client/functions/ogGetImageInfo new file mode 100755 index 0000000..f227f2c --- /dev/null +++ b/client/functions/ogGetImageInfo @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogGetImageInfo + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('imgfile') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetImageInfo', 'ogGetImageInfo path_filename', ['ogGetImageInfo /opt/opengnsys/images/prueba.img']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetImageInfo (args.imgfile) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetImageProgram b/client/functions/ogGetImageProgram new file mode 100755 index 0000000..80b2a15 --- /dev/null +++ b/client/functions/ogGetImageProgram @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogGetImageProgram + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('container') +parser.add_argument ('filename') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetImageProgram', 'ogGetImageProgram str_repo path_image', ['ogGetImageProgram REPO prueba']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetImageProgram (args.container, args.filename) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetImageSize b/client/functions/ogGetImageSize new file mode 100755 index 0000000..da45ec8 --- /dev/null +++ b/client/functions/ogGetImageSize @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogGetImageSize + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('repo') +parser.add_argument ('imgname') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetImageSize', 'ogGetImageSize str_repo path_image', ['ogGetImageSize REPO prueba']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetImageSize (args.repo, args.imgname) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetImageType b/client/functions/ogGetImageType new file mode 100755 index 0000000..304f030 --- /dev/null +++ b/client/functions/ogGetImageType @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogGetImageType + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('repo') +parser.add_argument ('imgname') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetImageType', 'ogGetImageType str_repo path_image', ['ogGetImageType REPO prueba']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetImageType (args.repo, args.imgname) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetIpAddress b/client/functions/ogGetIpAddress new file mode 100755 index 0000000..4a3e976 --- /dev/null +++ b/client/functions/ogGetIpAddress @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from NetLib import ogGetIpAddress + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetIpAddress') + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetIpAddress () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetLastSector b/client/functions/ogGetLastSector new file mode 100755 index 0000000..4723660 --- /dev/null +++ b/client/functions/ogGetLastSector @@ -0,0 +1,30 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogGetLastSector + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetLastSector', 'ogGetLastSector int_ndisk [int_npart]', ['ogGetLastSector 1'], ['ogGetLastSector 1 1']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 2 == len (sys.argv): + parser.add_argument ('disk') +elif 3 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') + +args = parser.parse_args() + +if 2 == len (sys.argv): + ret = ogGetLastSector (args.disk) +elif 3 == len (sys.argv): + ret = ogGetLastSector (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetMacAddress b/client/functions/ogGetMacAddress new file mode 100755 index 0000000..b3585f4 --- /dev/null +++ b/client/functions/ogGetMacAddress @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from NetLib import ogGetMacAddress + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetMacAddress') + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetMacAddress () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetMountPoint b/client/functions/ogGetMountPoint new file mode 100755 index 0000000..9cb0625 --- /dev/null +++ b/client/functions/ogGetMountPoint @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogGetMountPoint + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetMountPoint', 'ogGetMountPoint int_ndisk int_nfilesys', ['ogGetMountPoint 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetMountPoint (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetOsType b/client/functions/ogGetOsType new file mode 100755 index 0000000..77a6f29 --- /dev/null +++ b/client/functions/ogGetOsType @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from InventoryLib import ogGetOsType + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('partition') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetOsType', 'ogGetOsType int_ndisk int_npartition', ['ogGetOsType 1 2']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetOsType (args.disk, args.partition) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetOsUuid b/client/functions/ogGetOsUuid new file mode 100755 index 0000000..306d96c --- /dev/null +++ b/client/functions/ogGetOsUuid @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from InventoryLib import ogGetOsUuid + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetOsUuid', 'ogGetOsUuid int_ndisk int_nfilesys', ['ogGetOsUuid 1 2']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGetOsUuid (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetOsVersion b/client/functions/ogGetOsVersion new file mode 100755 index 0000000..a91fec6 --- /dev/null +++ b/client/functions/ogGetOsVersion @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from InventoryLib import ogGetOsVersion + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('part') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetOsVersion', 'ogGetOsVersion int_ndisk int_nfilesys', ['ogGetOsVersion 1 2']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetOsVersion (args.disk, args.part) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetParentPath b/client/functions/ogGetParentPath new file mode 100755 index 0000000..3051970 --- /dev/null +++ b/client/functions/ogGetParentPath @@ -0,0 +1,32 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileLib import ogGetParentPath + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetParentPath', 'ogGetParentPath [ str_repo | int_ndisk int_npartition ] path_filepath', ['ogGetParentPath /mnt/sda1/windows/system32', 'ogGetPath REPO /etc/fstab', 'ogGetPath 1 1 /windows/system32']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('src', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) +elif 4 == len (sys.argv): + parser.add_argument ('disk', nargs='?', default=None) + parser.add_argument ('par', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + +args = parser.parse_args() + +if 3 == len (sys.argv): + ret = ogGetParentPath (src=args.src, file=args.file) +elif 4 == len (sys.argv): + ret = ogGetParentPath (src=f'{args.disk} {args.par}', file=args.file) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetPartitionActive b/client/functions/ogGetPartitionActive new file mode 100755 index 0000000..ce516bc --- /dev/null +++ b/client/functions/ogGetPartitionActive @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogGetPartitionActive + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetPartitionActive', 'ogGetPartitionActive int_ndisk', ['ogGetPartitionActive 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetPartitionActive (args.disk) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetPartitionId b/client/functions/ogGetPartitionId new file mode 100755 index 0000000..dfcae9b --- /dev/null +++ b/client/functions/ogGetPartitionId @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogGetPartitionId + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetPartitionId', 'ogGetPartitionId int_ndisk int_npartition', ['ogGetPartitionId 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetPartitionId (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetPartitionSize b/client/functions/ogGetPartitionSize new file mode 100755 index 0000000..0ea7767 --- /dev/null +++ b/client/functions/ogGetPartitionSize @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogGetPartitionSize + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetPartitionSize', 'ogGetPartitionSize int_ndisk int_npartition', ['ogGetPartitionSize 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetPartitionSize (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetPartitionTableType b/client/functions/ogGetPartitionTableType new file mode 100755 index 0000000..262ad62 --- /dev/null +++ b/client/functions/ogGetPartitionTableType @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogGetPartitionTableType + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetPartitionTableType', 'ogGetPartitionTableType int_ndisk', ['ogGetPartitionTableType 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetPartitionTableType (args.disk) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetPartitionType b/client/functions/ogGetPartitionType new file mode 100755 index 0000000..51e6644 --- /dev/null +++ b/client/functions/ogGetPartitionType @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogGetPartitionType + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetPartitionType', 'ogGetPartitionType int_ndisk int_nfilesys', ['ogGetPartitionType 1 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGetPartitionType (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetPartitionsNumber b/client/functions/ogGetPartitionsNumber new file mode 100755 index 0000000..de6bbe7 --- /dev/null +++ b/client/functions/ogGetPartitionsNumber @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogGetPartitionsNumber + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetPartitionsNumber', 'ogGetPartitionsNumber int_ndisk', ['ogGetPartitionsNumber 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogGetPartitionsNumber (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetPath b/client/functions/ogGetPath new file mode 100755 index 0000000..d40cc5e --- /dev/null +++ b/client/functions/ogGetPath @@ -0,0 +1,36 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileLib import ogGetPath + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetPath', 'ogGetPath [ str_repo | int_ndisk int_npartition ] path_filepath', ['ogGetPath /mnt/sda1/windows/system32', 'ogGetPath REPO /etc/fstab', 'ogGetPath 1 1 /windows/system32']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 2 == len (sys.argv): + parser.add_argument ('file', nargs='?', default=None) +elif 3 == len (sys.argv): + parser.add_argument ('src', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) +elif 4 == len (sys.argv): + parser.add_argument ('disk', nargs='?', default=None) + parser.add_argument ('par', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + +args = parser.parse_args() + +if 2 == len (sys.argv): + ret = ogGetPath (file=args.file) +elif 3 == len (sys.argv): + ret = ogGetPath (src=args.src, file=args.file) +elif 4 == len (sys.argv): + ret = ogGetPath (src=f'{args.disk} {args.par}', file=args.file) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetRegistryValue b/client/functions/ogGetRegistryValue new file mode 100755 index 0000000..c3645a5 --- /dev/null +++ b/client/functions/ogGetRegistryValue @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from RegistryLib import ogGetRegistryValue + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('mntpt') +parser.add_argument ('hive') +parser.add_argument ('k') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetRegistryValue', 'ogGetRegistryValue path_mountpoint str_hive str_valuename', [r'ogGetRegistryValue /mnt/sda1 SOFTWARE "\Microsoft\NewKey\Value1"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetRegistryValue (args.mntpt, args.hive, args.k) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetRepoIp b/client/functions/ogGetRepoIp new file mode 100755 index 0000000..6d89ff6 --- /dev/null +++ b/client/functions/ogGetRepoIp @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from NetLib import ogGetRepoIp + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetRepoIp') + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetRepoIp () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetSerialNumber b/client/functions/ogGetSerialNumber new file mode 100755 index 0000000..dc02c8e --- /dev/null +++ b/client/functions/ogGetSerialNumber @@ -0,0 +1,17 @@ +#!/usr/bin/python3 + +import sys +from SystemLib import ogHelp +from InventoryLib import ogGetSerialNumber + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetSerialNumber', 'ogGetSerialNumber', ['ogGetSerialNumber']) + sys.exit (0) + +ret = ogGetSerialNumber() + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetServerIp b/client/functions/ogGetServerIp new file mode 100755 index 0000000..7f23a8f --- /dev/null +++ b/client/functions/ogGetServerIp @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from NetLib import ogGetServerIp + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetServerIp') + sys.exit (0) + +args = parser.parse_args() + +ret = ogGetServerIp () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGetSizeParameters b/client/functions/ogGetSizeParameters new file mode 100755 index 0000000..951f7a8 --- /dev/null +++ b/client/functions/ogGetSizeParameters @@ -0,0 +1,21 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogGetSizeParameters + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('container') +parser.add_argument ('imgname') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGetSizeParameters', 'ogGetSizeParameters num_disk num_part str_repo path_imgname', ['read SIZEDATA SIZEREQUIRED SIZEFREE ISENOUGHSPACE <<< $(ogGetSizeParameters 1 2 REPO Windows10)', 'read SIZEDATA SIZEREQUIRED SIZEFREE ISENOUGHSPACE <<< $(ogGetSizeParameters 1 6 CACHE Ubuntu16']) + sys.exit (0) + +args = parser.parse_args() +sizedata, sizerequired, sizefree, isenoughspace = ogGetSizeParameters (args.disk, args.par, args.container, args.imgname) +print (' '.join ([str(sizedata), str(sizerequired), str(sizefree), str(isenoughspace)])) diff --git a/client/functions/ogGrubInstallMbr b/client/functions/ogGrubInstallMbr new file mode 100755 index 0000000..97a7497 --- /dev/null +++ b/client/functions/ogGrubInstallMbr @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGrubInstallMbr + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('checkos', nargs='?', default='FALSE') +parser.add_argument ('kernelparam', nargs='?', default='') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGrubInstallMbr', 'ogGrubInstallMbr int_ndiskSecondStage int_partitionSecondStage bolean_Configure_2ndStage "param param"', ['ogGrubInstallMbr 1 1 FALSE', 'ogGrubInstallMbr 1 1 TRUE "nomodeset irqpoll pci=noacpi quiet splash"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGrubInstallMbr (args.disk, args.par, args.checkos, args.kernelparam) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogGrubInstallPartition b/client/functions/ogGrubInstallPartition new file mode 100755 index 0000000..eca057a --- /dev/null +++ b/client/functions/ogGrubInstallPartition @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogGrubInstallPartition + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('checkos', nargs='?', default='FALSE') +parser.add_argument ('kernelparam', nargs='?', default='') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogGrubInstallPartition', 'ogGrubInstallPartition int_ndiskSecondStage int_partitionSecondStage bolean_Configure_2ndStage "param param"', ['ogGrubInstallPartition 1 1 FALSE', 'ogGrubInstallPartition 1 1 TRUE "nomodeset irqpoll pci=noacpi quiet splash"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogGrubInstallPartition (args.disk, args.par, args.checkos, args.kernelparam) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogHelp b/client/functions/ogHelp new file mode 100755 index 0000000..e26329f --- /dev/null +++ b/client/functions/ogHelp @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from SystemLib import ogHelp + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('fname') +parser.add_argument ('fmt', nargs='?', default=None) +parser.add_argument ('examples', nargs='?', default=[]) + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogHelp') + sys.exit (0) + +args = parser.parse_args() + +ret = ogHelp (args.fname, args.fmt, args.examples) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogHidePartition b/client/functions/ogHidePartition new file mode 100755 index 0000000..2a97ce1 --- /dev/null +++ b/client/functions/ogHidePartition @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogHidePartition + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogHidePartition', 'ogHidePartition int_ndisk int_npartition', ['ogHidePartition 1 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogHidePartition (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIdToType b/client/functions/ogIdToType new file mode 100755 index 0000000..50bec6e --- /dev/null +++ b/client/functions/ogIdToType @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogIdToType + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('id') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIdToType', 'ogIdToType int_idpart', ['ogIdToType 83']) + sys.exit (0) + +args = parser.parse_args() +ret = ogIdToType (args.id) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogInstallFirstBoot b/client/functions/ogInstallFirstBoot new file mode 100755 index 0000000..ea54b00 --- /dev/null +++ b/client/functions/ogInstallFirstBoot @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from PostConfLib import ogInstallFirstBoot + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('cmdfile') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogInstallFirstBoot', 'ogInstallFirstBoot int_ndisk int_npartition str_filename', ['ogInstallFirstBoot 1 1 filename.cmd']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogInstallFirstBoot (args.disk, args.par, args.cmdfile) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogInstallMiniSetup b/client/functions/ogInstallMiniSetup new file mode 100755 index 0000000..4ffcec0 --- /dev/null +++ b/client/functions/ogInstallMiniSetup @@ -0,0 +1,35 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from PostConfLib import ogInstallMiniSetup + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogInstallMiniSetup', 'MSG_SEE ogInstallFirstBoot ogInstallRunonce') + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 4 == len (sys.argv): + parser.add_argument ('disk') + parser.add_argument ('par') + parser.add_argument ('cmdfile') + args = parser.parse_args() + ret = ogInstallMiniSetup (args.disk, args.par, args.cmdfile) +else: + parser.add_argument ('disk') + parser.add_argument ('par') + parser.add_argument ('cmdfile') + parser.add_argument ('user', nargs='?', default=None) + parser.add_argument ('pwd', nargs='?', default=None) + parser.add_argument ('autologin', nargs='?', default=False) + parser.add_argument ('userauto', nargs='?', default=None) + parser.add_argument ('pwdauto', nargs='?', default=None) + args = parser.parse_args() + ret = ogInstallMiniSetup (args.disk, args.par, args.cmdfile, args.user, args.pwd, args.autologin, args.userauto, args.pwdauto) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogInstallRunonce b/client/functions/ogInstallRunonce new file mode 100755 index 0000000..5d52354 --- /dev/null +++ b/client/functions/ogInstallRunonce @@ -0,0 +1,29 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from PostConfLib import ogInstallRunonce + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('cmdfile') +parser.add_argument ('user') +parser.add_argument ('pwd') +parser.add_argument ('autologin') +parser.add_argument ('userauto', nargs='?', default=None) +parser.add_argument ('pwdauto', nargs='?', default=None) + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogInstallRunonce', 'ogInstallRunonce int_ndisk int_npartition str_filename str_adm_user str_adm_password bool_autologin [str_auto_user str_auto_password]', ['ogInstallRunonce 1 1 filename.cmd administrator passadmin 1 userauto passuserauto', 'ogInstallRunonce 1 1 filename.cmd administrator passadmin 0']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogInstallRunonce (args.disk, args.par, args.cmdfile, args.user, args.pwd, args.autologin, args.userauto, args.pwdauto) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIsDiskLocked b/client/functions/ogIsDiskLocked new file mode 100755 index 0000000..25ebde8 --- /dev/null +++ b/client/functions/ogIsDiskLocked @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogIsDiskLocked + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIsDiskLocked', 'ogIsDiskLocked int_ndisk', ['ogIsDiskLocked 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogIsDiskLocked (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIsEfiActive b/client/functions/ogIsEfiActive new file mode 100755 index 0000000..099ef7b --- /dev/null +++ b/client/functions/ogIsEfiActive @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from InventoryLib import ogIsEfiActive + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIsEfiActive') + sys.exit (0) + +args = parser.parse_args() + +ret = ogIsEfiActive () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIsFormated b/client/functions/ogIsFormated new file mode 100755 index 0000000..3ab17f0 --- /dev/null +++ b/client/functions/ogIsFormated @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogIsFormated + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('part') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIsFormated', 'ogIsFormated int_ndisk int_nfilesys', ['ogIsFormated 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogIsFormated (args.disk, args.part) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIsImageLocked b/client/functions/ogIsImageLocked new file mode 100755 index 0000000..5d9bdb6 --- /dev/null +++ b/client/functions/ogIsImageLocked @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogIsImageLocked + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('container', nargs='?', default=None) +parser.add_argument ('imgfile', nargs='?', default=None) + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIsImageLocked', 'ogIsImageLocked [str_repo] path_image', ['ogIsImageLocked /opt/opengnsys/images/aula1/win7.img', 'ogIsImageLocked REPO /aula1/win7.img']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogIsImageLocked (args.container, args.imgfile) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIsLocked b/client/functions/ogIsLocked new file mode 100755 index 0000000..6523cf8 --- /dev/null +++ b/client/functions/ogIsLocked @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogIsLocked + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIsLocked', 'ogIsLocked int_ndisk int_nfilesys', ['ogIsLocked 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogIsLocked (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIsMounted b/client/functions/ogIsMounted new file mode 100755 index 0000000..1158a65 --- /dev/null +++ b/client/functions/ogIsMounted @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogIsMounted + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIsMounted', 'ogIsMounted int_ndisk int_nfilesys', ['ogIsMounted 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogIsMounted (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIsPartitionLocked b/client/functions/ogIsPartitionLocked new file mode 100755 index 0000000..f340264 --- /dev/null +++ b/client/functions/ogIsPartitionLocked @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogIsPartitionLocked + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIsPartitionLocked', 'ogIsPartitionLocked int_ndisk int_nfilesys', ['ogIsPartitionLocked 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogIsPartitionLocked (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIsReadonly b/client/functions/ogIsReadonly new file mode 100755 index 0000000..6a20026 --- /dev/null +++ b/client/functions/ogIsReadonly @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogIsReadonly + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIsReadonly', 'ogIsReadonly int_ndisk int_nfilesys', ['ogIsReadonly 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogIsReadonly (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIsRepoLocked b/client/functions/ogIsRepoLocked new file mode 100755 index 0000000..aad48d2 --- /dev/null +++ b/client/functions/ogIsRepoLocked @@ -0,0 +1,17 @@ +#!/usr/bin/python3 + +import sys +from SystemLib import ogHelp +from SystemLib import ogIsRepoLocked + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIsRepoLocked', 'ogIsRepoLocked', ['ogIsRepoLocked']) + sys.exit (0) + +ret = ogIsRepoLocked() + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIsVirtualMachine b/client/functions/ogIsVirtualMachine new file mode 100755 index 0000000..9592da3 --- /dev/null +++ b/client/functions/ogIsVirtualMachine @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from SystemLib import ogIsVirtualMachine + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIsVirtualMachine') + sys.exit (0) + +args = parser.parse_args() + +ret = ogIsVirtualMachine () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogIsWritable b/client/functions/ogIsWritable new file mode 100755 index 0000000..53e1314 --- /dev/null +++ b/client/functions/ogIsWritable @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogIsWritable + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogIsWritable', 'ogIsWritable int_ndisk int_nfilesys', ['ogIsWritable 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogIsWritable (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogListHardwareInfo b/client/functions/ogListHardwareInfo new file mode 100755 index 0000000..2eaa493 --- /dev/null +++ b/client/functions/ogListHardwareInfo @@ -0,0 +1,17 @@ +#!/usr/bin/python3 + +import sys +from SystemLib import ogHelp +from InventoryLib import ogListHardwareInfo + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogListHardwareInfo', 'ogListHardwareInfo', ['ogListHardwareInfo']) + sys.exit (0) + +ret = ogListHardwareInfo() + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogListLogicalPartitions b/client/functions/ogListLogicalPartitions new file mode 100755 index 0000000..c79a006 --- /dev/null +++ b/client/functions/ogListLogicalPartitions @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogListLogicalPartitions + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogListLogicalPartitions', 'ogListLogicalPartitions int_ndisk', ['ogListLogicalPartitions 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogListLogicalPartitions (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (' '.join (ret)) diff --git a/client/functions/ogListPartitions b/client/functions/ogListPartitions new file mode 100755 index 0000000..ca0479b --- /dev/null +++ b/client/functions/ogListPartitions @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogListPartitions + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogListPartitions', 'ogListPartitions int_ndisk', ['ogListPartitions 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogListPartitions (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (' '.join (ret)) diff --git a/client/functions/ogListPrimaryPartitions b/client/functions/ogListPrimaryPartitions new file mode 100755 index 0000000..045289f --- /dev/null +++ b/client/functions/ogListPrimaryPartitions @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogListPrimaryPartitions + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogListPrimaryPartitions', 'ogListPrimaryPartitions int_ndisk', ['ogListPrimaryPartitions 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogListPrimaryPartitions (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (' '.join (ret)) diff --git a/client/functions/ogListRegistryKeys b/client/functions/ogListRegistryKeys new file mode 100755 index 0000000..c56d829 --- /dev/null +++ b/client/functions/ogListRegistryKeys @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from RegistryLib import ogListRegistryKeys + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('mntpt') +parser.add_argument ('hive') +parser.add_argument ('k') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogListRegistryKeys', 'ogListRegistryKeys path_mountpoint str_hive str_key', [r'ogListRegistryKeys /mnt/sda1 SOFTWARE "\Microsoft\Windows\CurrentVersion"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogListRegistryKeys (args.mntpt, args.hive, args.k) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: + for k in ret: print (k) diff --git a/client/functions/ogListRegistryValues b/client/functions/ogListRegistryValues new file mode 100755 index 0000000..b6dcc78 --- /dev/null +++ b/client/functions/ogListRegistryValues @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from RegistryLib import ogListRegistryValues + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('mntpt') +parser.add_argument ('hive') +parser.add_argument ('k') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogListRegistryValues', 'ogListRegistryValues path_mountpoint str_hive str_key', [r'ogListRegistryValues /mnt/sda1 SOFTWARE "\Microsoft\Windows\CurrentVersion"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogListRegistryValues (args.mntpt, args.hive, args.k) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: + for k in ret: print (k) diff --git a/client/functions/ogListSoftware b/client/functions/ogListSoftware new file mode 100755 index 0000000..75abb9f --- /dev/null +++ b/client/functions/ogListSoftware @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from InventoryLib import ogListSoftware + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogListSoftware', 'ogListSoftware int_disk int_partition', ['ogListSoftware 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogListSoftware (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: + for k in ret: print (k) diff --git a/client/functions/ogLock b/client/functions/ogLock new file mode 100755 index 0000000..8bb795f --- /dev/null +++ b/client/functions/ogLock @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogLock + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogLock', 'ogLock int_ndisk int_nfilesys', ['ogLock 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogLock (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogLockDisk b/client/functions/ogLockDisk new file mode 100755 index 0000000..1b1e640 --- /dev/null +++ b/client/functions/ogLockDisk @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogLockDisk + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogLockDisk', 'ogLockDisk int_ndisk', ['ogLockDisk 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogLockDisk (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogLockImage b/client/functions/ogLockImage new file mode 100755 index 0000000..0c8f505 --- /dev/null +++ b/client/functions/ogLockImage @@ -0,0 +1,30 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogLockImage + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogLockImage', 'ogLockImage [str_repo] path_image', ['ogLockImage /opt/opengnsys/images/aula1/win7.img', 'ogLockImage REPO /aula1/win7.img']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 2 == len (sys.argv): + parser.add_argument ('file') +elif 3 == len (sys.argv): + parser.add_argument ('container') + parser.add_argument ('file') + +args = parser.parse_args() + +if 2 == len (sys.argv): + ret = ogLockImage (imgfile=args.file) +elif 3 == len (sys.argv): + ret = ogLockImage (container=args.container, imgfile=args.file) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogLockPartition b/client/functions/ogLockPartition new file mode 100755 index 0000000..e83da43 --- /dev/null +++ b/client/functions/ogLockPartition @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogLockPartition + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogLockPartition', 'ogLockPartition int_ndisk int_nfilesys', ['ogLockPartition 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogLockPartition (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogMakeDir b/client/functions/ogMakeDir new file mode 100755 index 0000000..b12f1c1 --- /dev/null +++ b/client/functions/ogMakeDir @@ -0,0 +1,32 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileLib import ogMakeDir + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogMakeDir', 'ogMakeDir [ str_repo | int_ndisk int_npartition ] path_dir', ['ogMakeDir 1 2 /tmp/newdir']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('container', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) +elif 4 == len (sys.argv): + parser.add_argument ('disk', nargs='?', default=None) + parser.add_argument ('par', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + +args = parser.parse_args() + +if 3 == len (sys.argv): + ret = ogMakeDir (container=args.container, file=args.file) +elif 4 == len (sys.argv): + ret = ogMakeDir (container=f'{args.disk} {args.par}', file=args.file) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogMcastReceiverFile b/client/functions/ogMcastReceiverFile new file mode 100755 index 0000000..2b33ac2 --- /dev/null +++ b/client/functions/ogMcastReceiverFile @@ -0,0 +1,39 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogMcastReceiverFile + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogMcastReceiverFile', 'ogMcastReceiverFile [ str_portMcast] [ [Relative_path_file] | [str_REPOSITORY path_file] | [int_ndisk int_npart path_file ] ]', ['ogMcastReceiverFile 9000 /PS1_PH1.img', 'ogMcastReceiverFile 9000 CACHE /aula1/PS2_PH4.img', 'ogMcastReceiverFile 9000 1 1 /isos/linux.iso']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('sess', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) +elif 4 == len (sys.argv): + parser.add_argument ('sess', nargs='?', default=None) + parser.add_argument ('container', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) +elif 5 == len (sys.argv): + parser.add_argument ('sess', nargs='?', default=None) + parser.add_argument ('disk', nargs='?', default=None) + parser.add_argument ('par', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + +args = parser.parse_args() + +if 3 == len (sys.argv): + ret = ogMcastReceiverFile (file=args.file, sess=args.sess) +elif 4 == len (sys.argv): + ret = ogMcastReceiverFile (container=args.container, file=args.file, sess=args.sess) +elif 5 == len (sys.argv): + ret = ogMcastReceiverFile (disk=args.disk, par=args.par, file=args.file, sess=args.sess) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogMcastReceiverPartition b/client/functions/ogMcastReceiverPartition new file mode 100755 index 0000000..45a8763 --- /dev/null +++ b/client/functions/ogMcastReceiverPartition @@ -0,0 +1,26 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogMcastReceiverPartition + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('sess') +parser.add_argument ('tool') +parser.add_argument ('compressor') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogMcastReceiverPartition', 'ogMcastReceiverPartition int_ndisk int_npart SessionMulticastCLIENT tools compresor', ['ogMcastReceiverPartition 1 1 9000 partclone lzop']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogMcastReceiverPartition (args.disk, args.par, args.sess, args.tool, args.compressor) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogMcastSendFile b/client/functions/ogMcastSendFile new file mode 100755 index 0000000..7ed75ed --- /dev/null +++ b/client/functions/ogMcastSendFile @@ -0,0 +1,46 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogMcastSendFile + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk', nargs='?', default=None) +parser.add_argument ('par', nargs='?', default=None) +parser.add_argument ('container', nargs='?', default=None) +parser.add_argument ('file', nargs='?', default=None) +parser.add_argument ('sess', nargs='?', default=None) + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogMcastSendFile', 'ogMcastSendFile [str_REPOSITORY] [int_ndisk int_npart] /Relative_path_file sesionMcast', ['ogMcastSendFile 1 1 /aula1/winxp.img sesionMcast', 'ogMcastSendFile REPO /aula1/ubuntu.iso sesionMcast', 'ogMcastSendFile CACHE /aula1/winxp.img sesionMcast', 'ogMcastSendFile /opt/opengnsys/images/aula1/hd500.vmx sesionMcast']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('file', nargs='?', default=None) + parser.add_argument ('sess', nargs='?', default=None) +elif 4 == len (sys.argv): + parser.add_argument ('container', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + parser.add_argument ('sess', nargs='?', default=None) +elif 5 == len (sys.argv): + parser.add_argument ('disk', nargs='?', default=None) + parser.add_argument ('par', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + parser.add_argument ('sess', nargs='?', default=None) + +args = parser.parse_args() + +if 3 == len (sys.argv): + ret = ogMcastSendFile (file=args.file, sess=args.sess) +elif 4 == len (sys.argv): + ret = ogMcastSendFile (container=args.container, file=args.file, sess=args.sess) +elif 5 == len (sys.argv): + ret = ogMcastSendFile (disk=args.disk, par=args.par, file=args.file, sess=args.sess) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogMcastSendPartition b/client/functions/ogMcastSendPartition new file mode 100755 index 0000000..7c8ea6e --- /dev/null +++ b/client/functions/ogMcastSendPartition @@ -0,0 +1,26 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogMcastSendPartition + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('sess') +parser.add_argument ('tool') +parser.add_argument ('compressor') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogMcastSendPartition', 'ogMcastSendPartition int_ndisk int_npart SessionMulticastSERVER tools compresor', ['ogMcastSendPartition 1 1 9000:full-duplex:239.194.37.31:50M:20:2 partclone lzop']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogMcastSendPartition (args.disk, args.par, args.sess, args.tool, args.compressor) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogMcastSyntax b/client/functions/ogMcastSyntax new file mode 100755 index 0000000..a595498 --- /dev/null +++ b/client/functions/ogMcastSyntax @@ -0,0 +1,34 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogMcastSyntax + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogMcastSyntax', 'ogMcastSyntax params', ['ogMcastSyntax SENDPARTITION str_sessionSERVER str_device str_tools str_level', 'ogMcastSyntax RECEIVERPARTITION str_sessionCLIENT str_device str_tools str_level', 'ogMcastSyntax SENDFILE str_sessionSERVER str_file', 'ogMcastSyntax RECEIVERFILE str_sessionCLIENT str_file', 'sessionServer syntax: portbase:method:mcastaddress:speed:nclients:ntimeWaitingUntilNclients', 'sessionServer example: 9000:full-duplex|half-duplex|broadcast:239.194.17.36:80M:50:60', 'sessionClient syntax: portbase', 'sessionClient example: 9000', 'sessionClient syntax: portbase:serverIP:TimeOut_session:TimeOut_transmision', 'sessionClient example: 9000:172.17.88.161:40:120']) + sys.exit (0) + +kwargs = {} +parser = argparse.ArgumentParser (add_help=False) +if 'SENDPARTITION' == sys.argv[1] or 'RECEIVERPARTITION' == sys.argv[1]: + parser.add_argument ('op') + parser.add_argument ('sess') + parser.add_argument ('device') + parser.add_argument ('tool') + parser.add_argument ('level') + args = parser.parse_args() + kwargs = { 'device': args.device, 'tool': args.tool, 'level': args.level } +elif 'SENDFILE' == sys.argv[1] or 'RECEIVERFILE' == sys.argv[1]: + parser.add_argument ('op') + parser.add_argument ('sess') + parser.add_argument ('file') + args = parser.parse_args() + kwargs = { 'file': args.file } + +ret = ogMcastSyntax (args.op, args.sess, **kwargs) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogMount b/client/functions/ogMount new file mode 100755 index 0000000..2a92f44 --- /dev/null +++ b/client/functions/ogMount @@ -0,0 +1,35 @@ +#!/usr/bin/python3 + +## this script doesn't call ogMount. It replicates the functionality instead. + +import sys +import argparse +from SystemLib import ogHelp +from CacheLib import ogMountCache +from FileSystemLib import ogMountCdrom, ogMountFs + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogMount') + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +done = False +if 2 == len (sys.argv): + if 'cache' == sys.argv[1].lower(): + done = True + ret = ogMountCache() + elif 'cdrom' == sys.argv[1].lower(): + done = True + ret = ogMountCdrom() + +if not done: + parser.add_argument ('disk') + parser.add_argument ('par') + args = parser.parse_args() + ret = ogMountFs (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogMountCache b/client/functions/ogMountCache new file mode 100755 index 0000000..8dd7578 --- /dev/null +++ b/client/functions/ogMountCache @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from CacheLib import ogMountCache + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogMountCache', 'ogMountCache') + sys.exit (0) + +args = parser.parse_args() + +ret = ogMountCache () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogMountCdrom b/client/functions/ogMountCdrom new file mode 100755 index 0000000..24db5f1 --- /dev/null +++ b/client/functions/ogMountCdrom @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogMountCdrom + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogMountCdrom', 'ogMountCdrom', ['ogMountCdrom']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogMountCdrom () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogMountFirstFs b/client/functions/ogMountFirstFs new file mode 100755 index 0000000..61f324d --- /dev/null +++ b/client/functions/ogMountFirstFs @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogMountFirstFs + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogMountFirstFs', 'ogMountFirstFs int_ndisk', ['ogMountFirstFs 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogMountFirstFs (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogMountFs b/client/functions/ogMountFs new file mode 100755 index 0000000..2e2bdcf --- /dev/null +++ b/client/functions/ogMountFs @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogMountFs + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogMountFs', 'ogMountFs int_ndisk int_nfilesys', ['ogMountFs 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogMountFs (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramActiveEntry b/client/functions/ogNvramActiveEntry new file mode 100755 index 0000000..9eee20a --- /dev/null +++ b/client/functions/ogNvramActiveEntry @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramActiveEntry + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('entry') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramActiveEntry', 'ogNvramActiveEntry [ Num_order_entry | Label_entry ]', ['ogNvramActiveEntry 2', 'ogNvramActiveEntry "Windows Boot Manager"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramActiveEntry (args.entry) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramAddEntry b/client/functions/ogNvramAddEntry new file mode 100755 index 0000000..1cffa53 --- /dev/null +++ b/client/functions/ogNvramAddEntry @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramAddEntry + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('bootlbl') +parser.add_argument ('bootldr') +parser.add_argument ('nvram_set', nargs='?', default=False) + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramAddEntry', 'ogNvramAddEntry Str_label_entry Str_boot_loader [ Bool_add_bootorder ]', ['ogNvramAddEntry 1 2 TRUE', 'ogNvramAddEntry grub /EFI/grub/grubx64.efi TRUE', 'ogNvramAddEntry Windows /EFI/Microsoft/Boot/bootmgfw.efi']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramAddEntry (args.bootlbl, args.bootldr, args.nvram_set) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramDeleteEntry b/client/functions/ogNvramDeleteEntry new file mode 100755 index 0000000..d8f7912 --- /dev/null +++ b/client/functions/ogNvramDeleteEntry @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramDeleteEntry + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('entry') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramDeleteEntry', 'ogNvramDeleteEntry [ Num_order_entry | Label_entry ]', ['ogNvramDeleteEntry 2', 'ogNvramAddEntry "Windows Boot Manager"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramDeleteEntry (args.entry) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramGetCurrent b/client/functions/ogNvramGetCurrent new file mode 100755 index 0000000..c2a393d --- /dev/null +++ b/client/functions/ogNvramGetCurrent @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramGetCurrent + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramGetCurrent') + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramGetCurrent () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramGetNext b/client/functions/ogNvramGetNext new file mode 100755 index 0000000..4cacb1d --- /dev/null +++ b/client/functions/ogNvramGetNext @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramGetNext + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramGetNext') + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramGetNext () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramGetOrder b/client/functions/ogNvramGetOrder new file mode 100755 index 0000000..ef80387 --- /dev/null +++ b/client/functions/ogNvramGetOrder @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramGetOrder + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramGetOrder') + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramGetOrder () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (','.join (ret)) diff --git a/client/functions/ogNvramGetTimeout b/client/functions/ogNvramGetTimeout new file mode 100755 index 0000000..15d1e8d --- /dev/null +++ b/client/functions/ogNvramGetTimeout @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramGetTimeout + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramGetTimeout') + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramGetTimeout () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramInactiveEntry b/client/functions/ogNvramInactiveEntry new file mode 100755 index 0000000..780213c --- /dev/null +++ b/client/functions/ogNvramInactiveEntry @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramInactiveEntry + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('entry') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramInactiveEntry', 'ogNvramInactiveEntry [ Num_order_entry | Label_entry ]', ['ogNvramInactiveEntry 2', 'ogNvramInactiveEntry "Windows Boot Manager"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramInactiveEntry (args.entry) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramList b/client/functions/ogNvramList new file mode 100755 index 0000000..d44c974 --- /dev/null +++ b/client/functions/ogNvramList @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramList + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramList') + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramList () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramPxeFirstEntry b/client/functions/ogNvramPxeFirstEntry new file mode 100755 index 0000000..208328e --- /dev/null +++ b/client/functions/ogNvramPxeFirstEntry @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramPxeFirstEntry + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramPxeFirstEntry') + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramPxeFirstEntry () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramSetNext b/client/functions/ogNvramSetNext new file mode 100755 index 0000000..7c8ee3d --- /dev/null +++ b/client/functions/ogNvramSetNext @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramSetNext + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('entry') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramSetNext', 'ogNvramSetNext [ Num_order_entry | Label_entry ]', ['ogNvramSetNext 2', 'ogNvramSetNext "Windows Boot Manager"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramSetNext (args.entry) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramSetOrder b/client/functions/ogNvramSetOrder new file mode 100755 index 0000000..13c22b4 --- /dev/null +++ b/client/functions/ogNvramSetOrder @@ -0,0 +1,16 @@ +#!/usr/bin/python3 + +import sys +from SystemLib import ogHelp +from UEFILib import ogNvramSetOrder + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramSetOrder', 'ogNvramSetOrder Num_order1 [ Num_order2 ] ...', ['ogNvramSetOrder 1 3']) + sys.exit (0) + +ret = ogNvramSetOrder (sys.argv[1:]) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogNvramSetTimeout b/client/functions/ogNvramSetTimeout new file mode 100755 index 0000000..d54f89a --- /dev/null +++ b/client/functions/ogNvramSetTimeout @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogNvramSetTimeout + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('t') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogNvramSetTimeout', 'ogNvramSetTimeout int_Timeout (seg)', ['ogNvramSetTimeout 2']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogNvramSetTimeout (args.t) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogRaiseError b/client/functions/ogRaiseError new file mode 100755 index 0000000..15c94a6 --- /dev/null +++ b/client/functions/ogRaiseError @@ -0,0 +1,34 @@ +#!/usr/bin/python3 + +import sys +import argparse +import ogGlobals +from SystemLib import ogHelp +from SystemLib import ogRaiseError + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogRaiseError', 'ogRaiseError [str_logfile ...] int_errorcode str_errormessage') + sys.exit (0) + +logtypes = [] +while True: + if sys.argv[1] in ['command', 'log', 'session']: + logtypes.append (sys.argv.pop (1)) + else: break + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('code') +parser.add_argument ('msg') +args = parser.parse_args() + +try: + code = getattr (ogGlobals, args.code) +except AttributeError: + print (f'unknown code {args.code}') + sys.exit (1) + +ret = ogRaiseError (logtypes, code, args.msg) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) diff --git a/client/functions/ogReduceFs b/client/functions/ogReduceFs new file mode 100755 index 0000000..999aa90 --- /dev/null +++ b/client/functions/ogReduceFs @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogReduceFs + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogReduceFs', 'ogReduceFs int_ndisk int_nfilesys', ['ogReduceFs 1 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogReduceFs (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogRestoreEfiBootLoader b/client/functions/ogRestoreEfiBootLoader new file mode 100755 index 0000000..7e72e37 --- /dev/null +++ b/client/functions/ogRestoreEfiBootLoader @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from UEFILib import ogRestoreEfiBootLoader + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogRestoreEfiBootLoader', 'ogRestoreEfiBootLoader int_ndisk int_part', ['ogRestoreEfiBootLoader 1 2']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogRestoreEfiBootLoader (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogRestoreImage b/client/functions/ogRestoreImage new file mode 100755 index 0000000..57a461c --- /dev/null +++ b/client/functions/ogRestoreImage @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogRestoreImage + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('repo') +parser.add_argument ('imgpath') +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogRestoreImage', 'ogRestoreImage str_repo path_image int_ndisk int_npart', ['ogRestoreImage REPO /aula1/win7 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogRestoreImage (args.repo, args.imgpath, args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogRestoreImageSyntax b/client/functions/ogRestoreImageSyntax new file mode 100755 index 0000000..40d80ee --- /dev/null +++ b/client/functions/ogRestoreImageSyntax @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogRestoreImageSyntax + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('imgfile') +parser.add_argument ('part') +parser.add_argument ('tool', nargs='?', default=None) +parser.add_argument ('level', nargs='?', default=None) + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogRestoreImageSyntax', 'ogRestoreImageSyntax filename partition [tool] [levelcompresor]', ['ogRestoreImageSyntax /opt/opengnsys/images/prueba.img /dev/sda1 [partclone] [lzop]']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogRestoreImageSyntax (args.imgfile, args.part, args.tool, args.level) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogSetPartitionActive b/client/functions/ogSetPartitionActive new file mode 100755 index 0000000..c8a97b8 --- /dev/null +++ b/client/functions/ogSetPartitionActive @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogSetPartitionActive + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogSetPartitionActive', 'ogSetPartitionActive int_ndisk int_npartition', ['ogSetPartitionActive 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogSetPartitionActive (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogSetPartitionId b/client/functions/ogSetPartitionId new file mode 100755 index 0000000..865051f --- /dev/null +++ b/client/functions/ogSetPartitionId @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogSetPartitionId + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('id') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogSetPartitionId', 'ogSetPartitionId int_ndisk int_npartition hex_partid', ['ogSetPartitionId 1 1 7']) + sys.exit (0) + +args = parser.parse_args() +ret = ogSetPartitionId (args.disk, args.par, args.id) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogSetPartitionSize b/client/functions/ogSetPartitionSize new file mode 100755 index 0000000..84d17b9 --- /dev/null +++ b/client/functions/ogSetPartitionSize @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogSetPartitionSize + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('size') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogSetPartitionSize', 'ogSetPartitionSize int_ndisk int_npartition int_size', ['ogSetPartitionSize 1 1 10000000']) + sys.exit (0) + +args = parser.parse_args() +ret = ogSetPartitionSize (args.disk, args.par, args.size) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogSetPartitionType b/client/functions/ogSetPartitionType new file mode 100755 index 0000000..875d0c4 --- /dev/null +++ b/client/functions/ogSetPartitionType @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogSetPartitionType + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('type') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogSetPartitionType', 'ogSetPartitionType int_ndisk int_npartition str_type', ['ogSetPartitionType 1 1 NTFS']) + sys.exit (0) + +args = parser.parse_args() +ret = ogSetPartitionType (args.disk, args.par, args.type) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogSetRegistryValue b/client/functions/ogSetRegistryValue new file mode 100755 index 0000000..d13d47f --- /dev/null +++ b/client/functions/ogSetRegistryValue @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from RegistryLib import ogSetRegistryValue + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('mntpt') +parser.add_argument ('hive') +parser.add_argument ('k') +parser.add_argument ('v') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogSetRegistryValue', 'ogSetRegistryValue path_mountpoint str_hive str_valuename str_data', [r'ogSetRegistryValue /mnt/sda1 SOFTWARE "\Key\SubKey\StringValue" "Abcde Fghij"', r'ogSetRegistryValue /mnt/sda1 SOFTWARE "\Key\SubKey\DwordValue" 1', r'ogSetRegistryValue /mnt/sda1 SOFTWARE "\Key\SubKey\BinaryValue" "04 08 0C 10"']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogSetRegistryValue (args.mntpt, args.hive, args.k, args.v) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogSetWindowsName b/client/functions/ogSetWindowsName new file mode 100755 index 0000000..d199c9d --- /dev/null +++ b/client/functions/ogSetWindowsName @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogSetWindowsName + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('name') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogSetWindowsName', 'ogSetWindowsName int_ndisk int_filesys str_name', ['ogSetWindowsName 1 1 PRACTICA-PC']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogSetWindowsName (args.disk, args.par, args.name) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogTorrentStart b/client/functions/ogTorrentStart new file mode 100755 index 0000000..778d512 --- /dev/null +++ b/client/functions/ogTorrentStart @@ -0,0 +1,39 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogTorrentStart + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogTorrentStart', 'ogTorrentStart [ str_repo] [ [Relative_path_fileTORRENT] | [str_REPOSITORY path_fileTORRENT] | [int_ndisk int_npart path_fileTORRENT ] ] SessionTorrent', ['ogTorrentStart CACHE /PS1_PH1.img.torrent seeder:10000', 'ogTorrentStart /opt/opengnsys/cache/linux.iso peer:60', 'ogTorrentStart 1 1 /linux.iso.torrent leecher:60']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('torrentfile', nargs='?', default=None) + parser.add_argument ('torrentsess', nargs='?', default=None) +elif 4 == len (sys.argv): + parser.add_argument ('container', nargs='?', default=None) + parser.add_argument ('torrentfile', nargs='?', default=None) + parser.add_argument ('torrentsess', nargs='?', default=None) +elif 5 == len (sys.argv): + parser.add_argument ('disk', nargs='?', default=None) + parser.add_argument ('par', nargs='?', default=None) + parser.add_argument ('torrentfile', nargs='?', default=None) + parser.add_argument ('torrentsess', nargs='?', default=None) + +args = parser.parse_args() + +if 3 == len (sys.argv): + ret = ogTorrentStart (torrentfile=args.torrentfile, torrentsess=args.torrentsess) +elif 4 == len (sys.argv): + ret = ogTorrentStart (container=args.container, torrentfile=args.torrentfile, torrentsess=args.torrentsess) +elif 5 == len (sys.argv): + ret = ogTorrentStart (disk=args.disk, par=args.par, torrentfile=args.torrentfile, torrentsess=args.torrentsess) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogTypeToId b/client/functions/ogTypeToId new file mode 100755 index 0000000..cce6665 --- /dev/null +++ b/client/functions/ogTypeToId @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogTypeToId + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('type') +parser.add_argument ('pttype', nargs='?', default='MSDOS') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogTypeToId', 'ogTypeToId str_parttype [str_tabletype]', ['ogTypeToId LINUX', 'ogTypeToId LINUX MSDOS']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogTypeToId (args.type, args.pttype) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUcastReceiverPartition b/client/functions/ogUcastReceiverPartition new file mode 100755 index 0000000..31fb177 --- /dev/null +++ b/client/functions/ogUcastReceiverPartition @@ -0,0 +1,26 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogUcastReceiverPartition + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('sess') +parser.add_argument ('tool') +parser.add_argument ('level') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUcastReceiverPartition', 'ogUcastReceiverPartition int_ndisk int_npart SessionMulticastCLIENT tools compresor', ['ogUcastReceiverPartition 1 1 8000:ipMASTER partclone lzop']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogUcastReceiverPartition (args.disk, args.par, args.sess, args.tool, args.level) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUcastSendFile b/client/functions/ogUcastSendFile new file mode 100755 index 0000000..498965a --- /dev/null +++ b/client/functions/ogUcastSendFile @@ -0,0 +1,39 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogUcastSendFile + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUcastSendFile', 'ogUcastSendFile [str_REPOSITORY] [int_ndisk int_npart] /Relative_path_file sesionMcast(puerto:ip:ip:ip)', ['ogUcastSendFile 1 1 /aula1/winxp.img 8000:172.17.36.11:172.17.36.12', 'ogUcastSendFile REPO /aula1/ubuntu.iso sesionUcast', 'ogUcastSendFile CACHE /aula1/winxp.img sesionUcast', 'ogUcastSendFile /opt/opengnsys/images/aula1/hd500.vmx sesionUcast']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 3 == len (sys.argv): + parser.add_argument ('file', nargs='?', default=None) + parser.add_argument ('sess', nargs='?', default=None) +elif 4 == len (sys.argv): + parser.add_argument ('container', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + parser.add_argument ('sess', nargs='?', default=None) +elif 5 == len (sys.argv): + parser.add_argument ('disk', nargs='?', default=None) + parser.add_argument ('par', nargs='?', default=None) + parser.add_argument ('file', nargs='?', default=None) + parser.add_argument ('sess', nargs='?', default=None) + +args = parser.parse_args() + +if 3 == len (sys.argv): + ret = ogUcastSendFile (file=args.file, sess=args.sess) +elif 4 == len (sys.argv): + ret = ogUcastSendFile (container=args.container, file=args.file, sess=args.sess) +elif 5 == len (sys.argv): + ret = ogUcastSendFile (disk=args.disk, par=args.par, file=args.file, sess=args.sess) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUcastSendPartition b/client/functions/ogUcastSendPartition new file mode 100755 index 0000000..8fba6dd --- /dev/null +++ b/client/functions/ogUcastSendPartition @@ -0,0 +1,26 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogUcastSendPartition + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('sess') +parser.add_argument ('tool') +parser.add_argument ('level') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUcastSendPartition', 'ogUcastSendPartition int_ndisk int_npart SessionUNICAST-SERVER tools compresor', ['ogUcastSendPartition 1 1 8000:172.17.36.11:172.17.36.12 partclone lzop']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogUcastSendPartition (args.disk, args.par, args.sess, args.tool, args.level) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUcastSyntax b/client/functions/ogUcastSyntax new file mode 100755 index 0000000..f360bc5 --- /dev/null +++ b/client/functions/ogUcastSyntax @@ -0,0 +1,34 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogUcastSyntax + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUcastSyntax', 'ogUcastSyntax params', ['ogUcastSyntax SENDPARTITION str_sessionSERVER str_device str_tools str_level', 'ogUcastSyntax RECEIVERPARTITION str_sessionCLIENT str_device str_tools str_level', 'ogUcastSyntax SENDFILE str_sessionSERVER str_file', 'ogUcastSyntax RECEIVERFILE str_sessionCLIENT str_file', 'sessionServer syntax: portbase:ipCLIENT-1:ipCLIENT-2:ipCLIENT-N', 'sessionServer example: 8000:172.17.36.11:172.17.36.12', 'sessionClient syntax: portbase:ipMASTER', 'sessionClient example: 8000:172.17.36.249']) + sys.exit (0) + +kwargs = {} +parser = argparse.ArgumentParser (add_help=False) +if 'SENDPARTITION' == sys.argv[1] or 'RECEIVERPARTITION' == sys.argv[1]: + parser.add_argument ('op') + parser.add_argument ('sess') + parser.add_argument ('device') + parser.add_argument ('tool') + parser.add_argument ('level') + args = parser.parse_args() + kwargs = { 'device': args.device, 'tool': args.tool, 'level': args.level } +elif 'SENDFILE' == sys.argv[1] or 'RECEIVERFILE' == sys.argv[1]: + parser.add_argument ('op') + parser.add_argument ('sess') + parser.add_argument ('file') + args = parser.parse_args() + kwargs = { 'file': args.file } + +ret = ogUcastSyntax (args.op, args.sess, **kwargs) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUnhidePartition b/client/functions/ogUnhidePartition new file mode 100755 index 0000000..539303e --- /dev/null +++ b/client/functions/ogUnhidePartition @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogUnhidePartition + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUnhidePartition', 'ogUnhidePartition int_ndisk int_npartition', ['ogUnhidePartition 1 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogUnhidePartition (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUninstallLinuxClient b/client/functions/ogUninstallLinuxClient new file mode 100755 index 0000000..0dfbe27 --- /dev/null +++ b/client/functions/ogUninstallLinuxClient @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from PostConfLib import ogUninstallLinuxClient + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUninstallLinuxClient', 'ogUninstallLinuxClient int_ndisk int_filesys', ['ogUninstallLinuxClient 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogUninstallLinuxClient (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUninstallWindowsClient b/client/functions/ogUninstallWindowsClient new file mode 100755 index 0000000..20ad443 --- /dev/null +++ b/client/functions/ogUninstallWindowsClient @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from PostConfLib import ogUninstallWindowsClient + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') +parser.add_argument ('cmdfile') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUninstallWindowsClient', 'ogUninstallWindowsClient int_ndisk int_filesys str_filename', ['ogUninstallWindowsClient 1 1 filename.cmd']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogUninstallWindowsClient (args.disk, args.par, args.cmdfile) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUnlock b/client/functions/ogUnlock new file mode 100755 index 0000000..ac321a2 --- /dev/null +++ b/client/functions/ogUnlock @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogUnlock + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUnlock', 'ogUnlock int_ndisk int_npartition', ['ogUnlock 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogUnlock (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUnlockDisk b/client/functions/ogUnlockDisk new file mode 100755 index 0000000..04ee6ed --- /dev/null +++ b/client/functions/ogUnlockDisk @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogUnlockDisk + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUnlockDisk', 'ogUnlockDisk int_ndisk', ['ogUnlockDisk 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogUnlockDisk (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUnlockImage b/client/functions/ogUnlockImage new file mode 100755 index 0000000..c0f5196 --- /dev/null +++ b/client/functions/ogUnlockImage @@ -0,0 +1,30 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ImageLib import ogUnlockImage + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUnlockImage', 'ogUnlockImage [str_repo] path_image', ['ogUnlockImage /opt/opengnsys/images/aula1/win7.img', 'ogUnlockImage REPO /aula1/win7.img']) + sys.exit (0) + +parser = argparse.ArgumentParser (add_help=False) +if 2 == len (sys.argv): + parser.add_argument ('file') +elif 3 == len (sys.argv): + parser.add_argument ('container') + parser.add_argument ('file') + +args = parser.parse_args() + +if 2 == len (sys.argv): + ret = ogUnlockImage (imgfile=args.file) +elif 3 == len (sys.argv): + ret = ogUnlockImage (container=args.container, imgfile=args.file) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUnlockPartition b/client/functions/ogUnlockPartition new file mode 100755 index 0000000..134c072 --- /dev/null +++ b/client/functions/ogUnlockPartition @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogUnlockPartition + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUnlockPartition') + sys.exit (0) + +args = parser.parse_args() + +ret = ogUnlockPartition (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUnmount b/client/functions/ogUnmount new file mode 100755 index 0000000..024294b --- /dev/null +++ b/client/functions/ogUnmount @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogUnmount + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUnmount', 'ogUnmount int_ndisk int_npartition', ['ogUnmount 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogUnmount (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUnmountAll b/client/functions/ogUnmountAll new file mode 100755 index 0000000..5b69eb7 --- /dev/null +++ b/client/functions/ogUnmountAll @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogUnmountAll + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUnmountAll', 'ogUnmountAll int_ndisk', ['ogUnmountAll 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogUnmountAll (args.disk) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUnmountCache b/client/functions/ogUnmountCache new file mode 100755 index 0000000..89a35fc --- /dev/null +++ b/client/functions/ogUnmountCache @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from CacheLib import ogUnmountCache + +parser = argparse.ArgumentParser (add_help=False) + + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUnmountCache', 'ogUnmountCache') + sys.exit (0) + +args = parser.parse_args() + +ret = ogUnmountCache () +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUnmountFs b/client/functions/ogUnmountFs new file mode 100755 index 0000000..8c83bc0 --- /dev/null +++ b/client/functions/ogUnmountFs @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogUnmountFs + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUnmountFs', 'ogUnmountFs int_ndisk int_npartition', ['ogUnmountFs 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogUnmountFs (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUnsetDirtyBit b/client/functions/ogUnsetDirtyBit new file mode 100755 index 0000000..c7314f2 --- /dev/null +++ b/client/functions/ogUnsetDirtyBit @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from FileSystemLib import ogUnsetDirtyBit + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUnsetDirtyBit', 'ogUnsetDirtyBit int_ndisk int_nfilesys', ['ogUnsetDirtyBit 1 1']) + sys.exit (0) + +args = parser.parse_args() +ret = ogUnsetDirtyBit (args.disk, args.par) + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUpdateCacheIsNecesary b/client/functions/ogUpdateCacheIsNecesary new file mode 100755 index 0000000..db05cec --- /dev/null +++ b/client/functions/ogUpdateCacheIsNecesary @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from ProtocolLib import ogUpdateCacheIsNecesary + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('repo') +parser.add_argument ('file') +parser.add_argument ('proto') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogUpdateCacheIsNecesary', 'ogUpdateCacheIsNecesary str_repo relative_path_image [protocol|FULL]', ['ogUpdateCacheIsNecesary REPO /PS1_PH1.img UNICAST', 'ogUpdateCacheIsNecesary REPO /ogclient.sqfs FULL']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogUpdateCacheIsNecesary (args.repo, args.file, args.proto) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogUpdatePartitionTable b/client/functions/ogUpdatePartitionTable new file mode 100755 index 0000000..8200b2a --- /dev/null +++ b/client/functions/ogUpdatePartitionTable @@ -0,0 +1,13 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from DiskLib import ogUpdatePartitionTable + +ret = ogUpdatePartitionTable() + +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogWindowsBootParameters b/client/functions/ogWindowsBootParameters new file mode 100755 index 0000000..3a410d9 --- /dev/null +++ b/client/functions/ogWindowsBootParameters @@ -0,0 +1,23 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogWindowsBootParameters + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogWindowsBootParameters', 'ogWindowsBootParameters int_ndisk int_partition', ['ogWindowsBootParameters 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogWindowsBootParameters (args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/functions/ogWindowsRegisterPartition b/client/functions/ogWindowsRegisterPartition new file mode 100755 index 0000000..34036bc --- /dev/null +++ b/client/functions/ogWindowsRegisterPartition @@ -0,0 +1,26 @@ +#!/usr/bin/python3 + +import sys +import argparse +from SystemLib import ogHelp +from BootLib import ogWindowsRegisterPartition + +parser = argparse.ArgumentParser (add_help=False) +parser.add_argument ('registered_disk') +parser.add_argument ('registered_par') +parser.add_argument ('registered_vol') +parser.add_argument ('disk') +parser.add_argument ('par') + +if 2 == len (sys.argv) and 'help' == sys.argv[1]: + #parser.print_help() sale en inglés aunque la locale indique otra cosa + ogHelp ('ogWindowsRegisterPartition', 'ogWindowsRegisterPartition int_ndisk_TO_register int_partition_TO_register str_NewVolume int_disk int_partition', ['ogWindowsRegisterPartition 1 1 c: 1 1']) + sys.exit (0) + +args = parser.parse_args() + +ret = ogWindowsRegisterPartition (args.registered_disk, args.registered_par, args.registered_vol, args.disk, args.par) +if ret is not None: + if ret == True: sys.exit (0) + elif ret == False: sys.exit (1) + else: print (ret) diff --git a/client/lib/python3/BootLib.py b/client/lib/python3/BootLib.py new file mode 100644 index 0000000..bf6f0b9 --- /dev/null +++ b/client/lib/python3/BootLib.py @@ -0,0 +1,1018 @@ +#/** +#@file BootLib.py +#@brief Librería o clase Boot +#@class Boot +#@brief Funciones para arranque y post-configuración de sistemas de archivos. +#@warning License: GNU GPLv3+ +#*/ + +import os +import re +import tempfile +import subprocess +import shutil +import glob + +import ogGlobals +import SystemLib +import FileSystemLib +import RegistryLib +import DiskLib +import InventoryLib +import FileLib +import UEFILib + +#/** +# ogBoot int_ndisk int_nfilesys [ NVRAMPERM ] [str_kernel str_initrd str_krnlparams] +#@brief Inicia el proceso de arranque de un sistema de archivos. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@param str_nvramperm UEFI: La entrada en la NVRAM se incluye en el orden de arranque (opcional) +#@param str_krnlparams parámetros de arranque del kernel (opcional) +#@return (activar el sistema de archivos). +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#@exception OG_ERR_NOTOS La partición no tiene instalado un sistema operativo. +#@note En Linux, si no se indican los parámetros de arranque se detectan de la opción por defecto del cargador GRUB. +#@note En Linux, debe arrancarse la partición del directorio \c /boot +#*/ ## + + +#/** +# ogGetWindowsName int_ndisk int_nfilesys +#@brief Muestra el nombre del equipo en el registro de Windows. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return str_name - nombre del equipo +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#*/ ## + + +#/** +# ogLinuxBootParameters int_ndisk int_nfilesys +#@brief Muestra los parámetros de arranque de un sistema de archivos Linux. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return str_kernel str_initrd str_parameters ... +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#@warning Función básica usada por \c ogBoot +#*/ ## + + +#/** +# ogSetWindowsName int_ndisk int_nfilesys str_name +#@brief Establece el nombre del equipo en el registro de Windows. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@param str_name nombre asignado +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#@exception OG_ERR_OUTOFLIMIT Nombre Netbios con más de 15 caracteres. +#*/ ## +def ogSetWindowsName (disk, par, name): + if len (name) > 15: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_OUTOFLIMIT, f'"{name[0:15]}..."') + return + + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: return None + + RegistryLib.ogSetRegistryValue (mntdir, 'system', r'\ControlSet001\Control\ComputerName\ComputerName\ComputerName', name) + RegistryLib.ogSetRegistryValue (mntdir, 'system', r'\ControlSet001\Services\Tcpip\Parameters\Hostname', name) + RegistryLib.ogSetRegistryValue (mntdir, 'system', r'\ControlSet001\Services\Tcpip\Parameters\HostName', name) + RegistryLib.ogSetRegistryValue (mntdir, 'system', r'\ControlSet001\services\Tcpip\Parameters\Hostname', name) + RegistryLib.ogSetRegistryValue (mntdir, 'system', r'\ControlSet001\Services\Tcpip\Parameters\NV Hostname', name) + RegistryLib.ogSetRegistryValue (mntdir, 'system', r'\ControlSet001\Services\Tcpip\Parameters\NV HostName', name) + RegistryLib.ogSetRegistryValue (mntdir, 'system', r'\ControlSet001\services\Tcpip\Parameters\NV Hostname', name) + + + +#/** +# ogSetWinlogonUser int_ndisk int_npartition str_username +#@brief Establece el nombre de usuario por defecto en la entrada de Windows. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@param str_username nombre de usuario por defecto +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#*/ ## + + +#/** +# ogBootMbrXP int_ndisk +#@brief Genera un nuevo Master Boot Record en el disco duro indicado, compatible con los SO tipo Windows +#@param int_ndisk nº de orden del disco +#@return salida del programa my-sys +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#*/ ## + + +#/** +# ogBootMbrGeneric int_ndisk +#@brief Genera un nuevo Codigo de arranque en el MBR del disco indicado, compatible con los SO tipo Windows, Linux. +#@param int_ndisk nº de orden del disco +#@return salida del programa my-sys +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Tipo de partición desconocido o no se puede montar. +#*/ ## + + + + +#/** +# ogFixBootSector int_ndisk int_parition +#@brief Corrige el boot sector de una particion activa para MS windows/dos -fat-ntfs +#@param int_ndisk nº de orden del disco +#@param int_partition nº de particion +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#*/ ## +def ogFixBootSector (disk, par): + partype = DiskLib.ogGetPartitionId (disk, par) + if partype not in [ '1', '4', '6', '7', 'b', 'c', 'e', 'f', '17', '700', 'EF00' ]: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, '') + return + + if not FileSystemLib.ogUnmount (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, '') + return + + disk0 = str (int (disk) - 1) + + tmpfile = tempfile.NamedTemporaryFile (prefix='ogFBS-', mode='w').name + with open (tmpfile, 'w') as fd: + fd.write (f"""disk={disk0} +main_part={par} +fix_first_sector=yes +""") + subprocess.run (['timeout', '--foreground', '--signal=SIGKILL', '5s', 'spartlnx.run', '-cui', '-nm', '-w', '-f', tmpfile], stdin=subprocess.DEVNULL) + + os.remove (tmpfile) + + +#/** +# ogGetBootMbr int_ndisk +#@brief Obtiene el contenido del sector de arranque de un disco. +#@param int_ndisk nº de orden del disco +#@return str_MBR Descripción del contenido del MBR. +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Dispositivo de disco no encontrado. +#*/ ## + +#/** +# ogWindowsBootParameters int_ndisk int_parition +#@brief Configura el gestor de arranque de windows 7 / vista / XP / 2000 +#@param int_ndisk nº de orden del disco +#@param int_partition nº de particion +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#*/ ## + +def ogWindowsBootParameters (disk, par): + if not DiskLib.ogDiskToDev (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, '') + return + + disk0 = int (disk) - 1 + + tmpfile = tempfile.NamedTemporaryFile (prefix='ogWBP-', mode='w').name + if InventoryLib.ogIsEfiActive(): + bootdisk, bootpar = DiskLib.ogGetEsp().split() + if not FileSystemLib.ogUnmount (bootdisk, bootpar): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'ESP: {bootdisk} {bootpar}') + return + bootdisk = str (int (bootdisk) - 1) + bootlabel = f'Part-{int(bootdisk):02d}-{int(bootpar):02d}' + bcdfile = f'boot_BCD_file=/EFI/{bootlabel}/Boot/BCD' + else: + bootdisk = disk0 + bootpar = par + bcdfile = '' + + +# Obtener versión de Windows. + winver = InventoryLib.ogGetOsVersion (disk, par) + parts = re.split (':| ', winver) + if 'Windows' == parts[0] and 'Server' == parts[2]: + winver = parts[1] + parts[2] + parts[3] + else: + winver = parts[1] + parts[2] + if not winver: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, 'Windows') + return + +# Acciones para Windows XP. + if 'XP' in winver: + m = FileSystemLib.ogMount (disk, par) + if not m or not os.path.exists (f'{m}/boot.ini'): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'boot.ini') + return + with open (f'{m}/boot.ini', 'r') as fd: + boot_ini = fd.read() + boot_ini = re.sub (r'partition\([0-9]\)', f'partition({par})', boot_ini) + boot_ini = re.sub (r'rdisk\([0-9]\)', f'rdisk({disk0})', boot_ini) + with open (f'{m}/tmp.boot.ini', 'w') as fd: + fd.write (boot_ini) + os.rename (f'{m}/tmp.boot.ini', f'{m}/boot.ini') + return True + + if not FileSystemLib.ogUnmount (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, '') + return + + +#Preparando instruccion Windows Resume Application + with open (tmpfile, 'w') as fd: + fd.write (f"""boot_disk={bootdisk} +boot_main_part={bootpar} +{bcdfile} +disk={disk0} +main_part={par} +boot_entry=Windows Resume Application +""") + subprocess.run (['timeout', '--foreground', '--signal=SIGKILL', '5s', 'spartlnx.run', '-cui', '-nm', '-w', '-f', tmpfile], stdin=subprocess.DEVNULL) + + +#Preparando instruccion tipo windows + with open (tmpfile, 'w') as fd: + fd.write (f"""boot_disk={bootdisk} +boot_main_part={bootpar} +{bcdfile} +disk={disk0} +main_part={par} +boot_entry={winver} +""") + subprocess.run (['timeout', '--foreground', '--signal=SIGKILL', '5s', 'spartlnx.run', '-cui', '-nm', '-w', '-f', tmpfile], stdin=subprocess.DEVNULL) + +##Preparando instruccion Ramdisk Options + with open (tmpfile, 'w') as fd: + fd.write (f"""boot_disk={bootdisk} +boot_main_part={bootpar} +{bcdfile} +disk={disk0} +main_part={par} +boot_entry=Ramdisk Options +""") + subprocess.run (['timeout', '--foreground', '--signal=SIGKILL', '5s', 'spartlnx.run', '-cui', '-nm', '-w', '-f', tmpfile], stdin=subprocess.DEVNULL) + +##Preparando instruccion Recovery Environment + with open (tmpfile, 'w') as fd: + fd.write (f"""boot_disk={bootdisk} +boot_main_part={bootpar} +{bcdfile} +disk={disk0} +main_part={par} +boot_entry=Windows Recovery Environment +""") + subprocess.run (['timeout', '--foreground', '--signal=SIGKILL', '5s', 'spartlnx.run', '-cui', '-nm', '-w', '-f', tmpfile], stdin=subprocess.DEVNULL) + +##Preparando instruccion Recovery + with open (tmpfile, 'w') as fd: + fd.write (f"""boot_disk={bootdisk} +boot_main_part={bootpar} +{bcdfile} +disk={disk0} +main_part={par} +boot_entry=Windows Recovery +""") + subprocess.run (['timeout', '--foreground', '--signal=SIGKILL', '5s', 'spartlnx.run', '-cui', '-nm', '-w', '-f', tmpfile], stdin=subprocess.DEVNULL) + +#Preparando instruccion Windows Boot Manager + with open (tmpfile, 'w') as fd: + fd.write (f"""boot_disk={bootdisk} +boot_main_part={bootpar} +{bcdfile} +disk={bootdisk} +main_part={bootpar} +boot_entry=Windows Boot Manager +""") + subprocess.run (['timeout', '--foreground', '--signal=SIGKILL', '5s', 'spartlnx.run', '-cui', '-nm', '-w', '-f', tmpfile], stdin=subprocess.DEVNULL) + +#Preparando instruccion Herramienta de diagnóstico de memoria de Windows + with open (tmpfile, 'w') as fd: + fd.write (f"""boot_disk={bootdisk} +boot_main_part={bootpar} +{bcdfile} +disk={bootdisk} +main_part={bootpar} +boot_entry=Herramienta de diagnóstico de memoria de Windows +""") + subprocess.run (['timeout', '--foreground', '--signal=SIGKILL', '5s', 'spartlnx.run', '-cui', '-nm', '-w', '-f', tmpfile], stdin=subprocess.DEVNULL) + +#Preparando instruccion Herramienta de diagnóstico de memoria de Windows + with open (tmpfile, 'w') as fd: + fd.write (f"""boot_disk={bootdisk} +boot_main_part={bootpar} +{bcdfile} +disk={bootdisk} +main_part={bootpar} +boot_entry=Herramienta de diagnstico de memoria de Windows +""") + subprocess.run (['timeout', '--foreground', '--signal=SIGKILL', '5s', 'spartlnx.run', '-cui', '-nm', '-w', '-f', tmpfile], stdin=subprocess.DEVNULL) + + os.remove (tmpfile) + + + +#/** +# ogWindowsRegisterPartition int_ndisk int_partiton str_volume int_disk int_partition +#@brief Registra una partición en windows con un determinado volumen. +#@param int_ndisk nº de orden del disco a registrar +#@param int_partition nº de particion a registrar +#@param str_volumen volumen a resgistar +#@param int_ndisk_windows nº de orden del disco donde esta windows +#@param int_partition_windows nº de particion donde esta windows +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#*/ ## +#ogWindowsRegisterPartition ("1", "1", "c:", "1", "1") +def ogWindowsRegisterPartition (registered_disk, registered_par, registered_vol, disk, par): + registered_vol = registered_vol[0].upper() + tmpfile = tempfile.NamedTemporaryFile (prefix='ogWRP-', mode='w').name + + if not DiskLib.ogDiskToDev (registered_disk, registered_par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'particion a registrar') + return + + if not DiskLib.ogDiskToDev (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'particion de windows') + return + + t = InventoryLib.ogGetOsType (disk, par) + if 'Windows' not in t: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, 'no es windows') + return + + v = InventoryLib.ogGetOsVersion (disk, par) + + if FileLib.ogGetPath (src=f'{disk} {par}', file='WINDOWS'): + systemroot = 'Windows' + elif FileLib.ogGetPath (src=f'{disk} {par}', file='WINNT'): + systemroot = 'winnt' + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, '') + return + + FileSystemLib.ogUnmount (disk, par) + disk0 = str (int (disk) - 1) + registered_disk0 = str (int (registered_disk) - 1) + + with open (tmpfile, 'w') as fd: + fd.write (f"""windows_disk={disk0} +windows_main_part={par} +windows_dir={systemroot} +disk={registered_disk0} +main_part={registered_par} +;ext_part +part_letter={registered_vol} +""") + subprocess.run (['timeout', '--foreground', '--signal=SIGKILL', '5s', 'spartlnx.run', '-cui', '-nm', '-w', '-f', tmpfile], stdin=subprocess.DEVNULL) + + os.remove (tmpfile) + + +#/** +# ogGrubInstallMbr int_disk_GRUBCFG int_partition_GRUBCFG +#@brief Instala el grub el el MBR del primer disco duro (FIRSTSTAGE). El fichero de configuración grub.cfg ubicado según parametros disk y part(SECONDSTAGE). Admite sistemas Windows. +#@param int_disk_SecondStage +#@param int_part_SecondStage +#@param bolean_Check_Os_installed_and_Configure_2ndStage true | false[default] +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#*/ ## + +#ogGrubInstallMbr ('1', '1', 'FALSE') +#ogGrubInstallMbr ('1', '1', 'TRUE', 'nomodeset irqpoll pci=noacpi quiet splash') +def ogGrubInstallMbr (disk, par, checkos='FALSE', kernelparam=''): + backupname = '.backup.og' + + #error si no es linux. + #version = InventoryLib.ogGetOsVersion (disk, par) + #if not version or 'Linux' not in version: + # SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, 'no es linux') + # return + + firststage = DiskLib.ogDiskToDev ('1') #La primera etapa del grub se fija en el primer disco duro + secondstage = FileSystemLib.ogMount (disk, par) #localizar disco segunda etapa del grub + if not secondstage: return + os.makedirs (f'{secondstage}/boot/grub/', exist_ok=True) + prefixsecondstage = '/boot/grubMBR' #Localizar directorio segunda etapa del grub + efioptgrub = [] + + if InventoryLib.ogIsEfiActive(): + esp = DiskLib.ogGetEsp() + efidisk, efipart = esp.split() + # Comprobamos que exista ESP y el directorio para ubuntu + efisecondstage = FileSystemLib.ogMount (efidisk, efipart) + if not efisecondstage: + FileSystemLib.ogFormat (efidisk, efipart, 'FAT32') + efisecondstage = FileSystemLib.ogMount (efidisk, efipart) + if not efisecondstage: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP') + return + efisubdir = 'grub' + if os.path.isdir (f'{efisecondstage}/EFI/{efisubdir}'): # Borramos la configuración anterior + shutil.rmtree (f'{efisecondstage}/EFI/{efisubdir}') + os.makedirs (f'{efisecondstage}/EFI/{efisubdir}/Boot') + arch = InventoryLib.ogGetArch() + efioptgrub = ['--removable', '--no-nvram', '--uefi-secure-boot', '--target', f'{arch}-efi', f'--efi-directory={efisecondstage}/EFI/{efisubdir}'] + + # Si Reconfigurar segunda etapa (grub.cfg) == FALSE + if 'FALSE' == checkos.upper() and (os.path.exists (f'{secondstage}/boot/grub/grub.cfg') or os.path.exists (f'{secondstage}/boot/grub/grub.cfg{backupname}')): + if os.path.exists (f'{secondstage}/boot/grub/grub.cfg{backupname}'): + os.rename (f'{secondstage}/boot/grub/grub.cfg{backupname}', f'{secondstage}/boot/grub/grub.cfg') + if os.path.isdir (f'{secondstage}{prefixsecondstage}'): + shutil.rmtree (f'{secondstage}{prefixsecondstage}') + prefixsecondstage = '' # Reactivamos el grub con el grub.cfg original. + else: # SI Reconfigurar segunda etapa (grub.cfg) == TRUE + #llamada a updateBootCache para que aloje la primera fase del ogLive + subprocess.run ([f'{ogGlobals.OGSCRIPTS}/updateBootCache.py'], check=True) ## TODO: check that this works + + if InventoryLib.ogIsEfiActive(): + # UEFI: grubSintax necesita grub.cfg para detectar los kernels: si no existe recupero backup. + if not os.path.exists (f'{secondstage}/boot/grub/grub.cfg'): + if os.path.exists (f'{secondstage}/boot/grub/grub.cfg{backupname}'): + os.rename (f'{secondstage}/boot/grub/grub.cfg{backupname}', f'{secondstage}/boot/grub/grub.cfg') + else: + os.rename (f'{secondstage}/boot/grub/grub.cfg', f'{secondstage}/boot/grub/grub.cfg{backupname}') + + with open ('/etc/default/grub', 'a') as fd: #Configur la sintaxis grub para evitar menus de "recovery" en el OGLive + fd.write ('GRUB_DISABLE_RECOVERY="true"\n') + fd.write ('GRUB_DISABLE_LINUX_UUID="true"\n') + + os.makedirs (f'{secondstage}{prefixsecondstage}/boot/grub/') #Preparar configuración segunda etapa: crear ubicacion + subprocess.run (['sed', '-i', 's/^set -e/#set -e/', '/etc/grub.d/00_header']) #Preparar configuración segunda etapa: crear cabecera del fichero (ingnorar errores) + # (ogLive 5.0) Si 'pkgdatadir' está vacía ponemos valor de otros ogLive + subprocess.run (['sed', '-i', r'/grub-mkconfig_lib/i\pkgdatadir=${pkgdatadir:-"${datarootdir}/grub"}', '/etc/grub.d/00_header']) + out = subprocess.run (['/etc/grub.d/00_header'], capture_output=True, text=True).stdout + with open (f'{secondstage}{prefixsecondstage}/boot/grub/grub.cfg', 'w') as fd: + fd.write (out + '\n') + + #Preparar configuración segunda etapa: crear entrada del sistema operativo + out = subprocess.run (['grubSyntax', kernelparam], capture_output=True, text=True).stdout + with open (f'{secondstage}{prefixsecondstage}/boot/grub/grub.cfg', 'a') as fd: + fd.write (out + '\n') + + # Renombramos la configuración de grub antigua + if os.path.exists (f'{secondstage}/boot/grub/grub.cfg'): + os.rename (f'{secondstage}/boot/grub/grub.cfg', f'{secondstage}/boot/grub/grub.cfg{backupname}') + + eval = subprocess.run (['grub-install', '--force'] + efioptgrub + [f'--root-directory={secondstage}{prefixsecondstage}', firststage]).returncode + + if InventoryLib.ogIsEfiActive(): # Movemos el grubx64.efi + for b in (glob.glob (f'{efisecondstage}/EFI/{efisubdir}/EFI/BOOT/*')): + bn = os.path.basename (b) + os.rename (f'{efisecondstage}/EFI/{efisubdir}/EFI/BOOT/{bn}', f'{efisecondstage}/EFI/{efisubdir}/Boot/{bn}') + shutil.rmtree (f'{efisecondstage}/EFI/{efisubdir}/EFI') + shutil.copy2 ('/usr/lib/shim/shimx64.efi.signed', f'{efisecondstage}/EFI/{efisubdir}/Boot/shimx64.efi') + # Nombre OpenGnsys para cargador + shutil.copy2 (f'{efisecondstage}/EFI/{efisubdir}/Boot/grubx64.efi', f'{efisecondstage}/EFI/{efisubdir}/Boot/ogloader.efi') + + # Creamos entrada NVRAM y la ponemos en segundo lugar + UEFILib.ogNvramAddEntry ('grub', '/EFI/grub/Boot/shimx64.efi') + grubentry = UEFILib.ogNvramList() + for l in grubentry.splitlines(): + words = l.split() + if len(words) < 2: continue + if 'grub' == words[1]: + grubentry = words[0] + neworder = UEFILib.ogNvramGetOrder() + neworder = neworder[0:1] + [grubentry] + neworder[1:] ## la ponemos en segundo lugar + UEFILib.ogNvramSetOrder (neworder) + + return eval + + +#/** +# ogGrubInstallPartition int_disk_SECONDSTAGE int_partition_SECONDSTAGE bolean_Check_Os_installed_and_Configure_2ndStage +#@brief Instala y actualiza el gestor grub en el bootsector de la particion indicada +#@param int_disk_SecondStage +#@param int_part_SecondStage +#@param bolean_Check_Os_installed_and_Configure_2ndStage true | false[default] +#@param str "kernel param " +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#*/ ## + +#ogGrubInstallPartition ('1', '1', 'FALSE') +#ogGrubInstallPartition ('1', '1', 'TRUE', 'nomodeset irqpoll pci=noacpi quiet splash') +def ogGrubInstallPartition (disk, par, checkos='FALSE', kernelparam=''): + backupname = '.backup.og' + + #error si no es linux. + version = InventoryLib.ogGetOsVersion (disk, par) + if not version or 'Linux' not in version: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, 'no es linux') + return + + firststage = DiskLib.ogDiskToDev (disk, par) #Localizar primera etapa del grub + secondstage = FileSystemLib.ogMount (disk, par) #localizar disco segunda etapa del grub + prefixsecondstage = '/boot/grubPARTITION' #Localizar directorio segunda etapa del grub + efioptgrub = [] + + if InventoryLib.ogIsEfiActive(): + esp = DiskLib.ogGetEsp() + efidisk, efipart = esp.split() + # Comprobamos que exista ESP y el directorio para ubuntu + efisecondstage = FileSystemLib.ogMount (efidisk, efipart) + if not efisecondstage: + FileSystemLib.ogFormat (efidisk, efipart, 'FAT32') + efisecondstage = FileSystemLib.ogMount (efidisk, efipart) + if not efisecondstage: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'ESP') + return + efisubdir = f'Part-{int(disk):02d}-{int(par):02d}' + if os.path.isdir (f'{efisecondstage}/EFI/{efisubdir}'): # Borramos la configuración anterior + shutil.rmtree (f'{efisecondstage}/EFI/{efisubdir}') + os.makedirs (f'{efisecondstage}/EFI/{efisubdir}/Boot') + arch = InventoryLib.ogGetArch() + efioptgrub = ['--removable', '--no-nvram', '--uefi-secure-boot', '--target', f'{arch}-efi', f'--efi-directory={efisecondstage}/EFI/{efisubdir}'] + + # Si Reconfigurar segunda etapa (grub.cfg) == FALSE + if 'FALSE' == checkos.upper() and (os.path.exists (f'{secondstage}/boot/grub/grub.cfg') or os.path.exists (f'{secondstage}/boot/grub/grub.cfg{backupname}')): + if os.path.exists (f'{secondstage}/boot/grub/grub.cfg{backupname}'): + os.rename (f'{secondstage}/boot/grub/grub.cfg{backupname}', f'{secondstage}/boot/grub/grub.cfg') + if os.path.isdir (f'{secondstage}{prefixsecondstage}'): + shutil.rmtree (f'{secondstage}{prefixsecondstage}') + prefixsecondstage = '' # Reactivamos el grub con el grub.cfg original. + else: # SI Reconfigurar segunda etapa (grub.cfg) == TRUE + if InventoryLib.ogIsEfiActive(): + # UEFI: grubSintax necesita grub.cfg para detectar los kernels: si no existe recupero backup. + if not os.path.exists (f'{secondstage}/boot/grub/grub.cfg'): + if os.path.exists (f'{secondstage}/boot/grub/grub.cfg{backupname}'): + os.rename (f'{secondstage}/boot/grub/grub.cfg{backupname}', f'{secondstage}/boot/grub/grub.cfg') + else: + if (os.path.exists (f'{secondstage}/boot/grub/grub.cfg')): + os.rename (f'{secondstage}/boot/grub/grub.cfg', f'{secondstage}/boot/grub/grub.cfg{backupname}') + + with open ('/etc/default/grub', 'a') as fd: #Configur la sintaxis grub para evitar menus de "recovery" en el OGLive + fd.write ('GRUB_DISABLE_RECOVERY="true"\n') + fd.write ('GRUB_DISABLE_LINUX_UUID="true"\n') + + os.makedirs (f'{secondstage}{prefixsecondstage}/boot/grub/', exist_ok=True) #Preparar configuración segunda etapa: crear ubicacion + subprocess.run (['sed', '-i', 's/^set -e/#set -e/', '/etc/grub.d/00_header']) #Preparar configuración segunda etapa: crear cabecera del fichero (ingnorar errores) + # (ogLive 5.0) Si 'pkgdatadir' está vacía ponemos valor de otros ogLive + subprocess.run (['sed', '-i', r'/grub-mkconfig_lib/i\pkgdatadir=${pkgdatadir:-"${datarootdir}/grub"}', '/etc/grub.d/00_header']) + out = subprocess.run (['/etc/grub.d/00_header'], capture_output=True, text=True).stdout + with open (f'{secondstage}{prefixsecondstage}/boot/grub/grub.cfg', 'w') as fd: + fd.write (out + '\n') + + #Preparar configuración segunda etapa: crear entrada del sistema operativo + out = subprocess.run (['grubSyntax', disk, par, kernelparam], capture_output=True, text=True).stdout + with open (f'{secondstage}{prefixsecondstage}/boot/grub/grub.cfg', 'a') as fd: + fd.write (out + '\n') + + eval = subprocess.run (['grub-install', '--force'] + efioptgrub + [f'--root-directory={secondstage}{prefixsecondstage}', firststage]).returncode + + if InventoryLib.ogIsEfiActive(): # Movemos el grubx64.efi + for b in (glob.glob (f'{efisecondstage}/EFI/{efisubdir}/EFI/BOOT/*')): + os.rename (f'{efisecondstage}/EFI/{efisubdir}/EFI/BOOT/{b}', f'{efisecondstage}/EFI/{efisubdir}/Boot/{b}') + shutil.rmtree (f'{efisecondstage}/EFI/{efisubdir}/EFI') + shutil.copy2 ('/usr/lib/shim/shimx64.efi.signed', f'{efisecondstage}/EFI/{efisubdir}/Boot/shimx64.efi') + # Nombre OpenGnsys para cargador + shutil.copy2 (f'{efisecondstage}/EFI/{efisubdir}/Boot/grubx64.efi', f'{efisecondstage}/EFI/{efisubdir}/Boot/ogloader.efi') + + return eval + + + +#/** +# ogConfigureFstab int_ndisk int_nfilesys +#@brief Configura el fstab según particiones existentes +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND No se encuentra el fichero fstab a procesar. +#@warning Puede haber un error si hay más de 1 partición swap. +#*/ ## +def ogConfigureFstab (disk, par): + fstab = FileLib.ogGetPath (src=f'{disk} {par}', file='/etc/fstab') + if not fstab: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{disk},{par},/etc/fstab') + return + + efiopt = '' + + shutil.copy2 (fstab, fstab+'.backup') + + with open ('/etc/fstab', 'r') as fd: + while True: + l = fd.readline() + if not l: break + cosas = l.split() + if 6 != len (cosas): continue + fstab_dev, fstab_mntpt, fstab_fstype, fstab_opts, fstab_dump, fstab_pass = cosas + if '#' in fstab_dev: continue + if '/' == fstab_mntpt: + defroot = fstab_dev + elif 'swap' == fstab_fstype: + defswap = fstab_dev + elif '/boot/efi' == fstab_mntpt: + efiopt = '\t'.join ([fstab_fstype, fstab_opts, fstab_dump, fstab_pass]) + + partroot = DiskLib.ogDiskToDev (disk, par) + partswap = subprocess.run (['blkid', '-', ' TYPE=swap'], capture_output=True, text=True).stdout + if partswap: + partswap = partswap.splitlines()[0] + partswap = partswap.split (':')[0] + if defswap: + print ("Hay definicion de SWAP en el FSTAB $DEFSWAP -> modificamos fichero con nuevo valor $DEFSWAP->$PARTSWAP") # Mensaje temporal. + subprocess.run (f'sed "s|{defswap}|{partswap}|g; s|{defroot}|{partroot}|g" {fstab}.backup > {fstab}', shell=True) + else: + print ("No hay definicion de SWAP y si hay partición SWAP -> moficamos fichero") # Mensaje temporal. + subprocess.run (f'sed "s|{defroot}|{partroot}|g" {fstab}.backup > {fstab}', shell=True) + with open ('/etc/fstab', 'a') as fd: + fd.write (f'{partswap} none swap sw 0 0\n') + else: + print ("No hay partición SWAP -> configuramos FSTAB") # Mensaje temporal. + subprocess.run (f'sed "/swap/d" {fstab}.backup > {fstab}', shell=True) +# Si es un sistema EFI incluimos partición ESP (Si existe la modificamos) + if InventoryLib.ogIsEfiActive(): + esp = DiskLib.ogGetEsp() + efidisk, efipart = esp.split() + efidev = DiskLib.ogDiskToDev (efidisk, efipart) + + ## Opciones de la partición ESP: si no existe ponemos un valor por defecto + if not efiopt: + efiopt = '\t'.join (['vfat', 'umask=0077', '0', '1']) + + subprocess.run (f'sed -i /"boot\\/efi"/d {fstab}', shell=True) + with open ('/etc/fstab', 'a') as fd: + fd.write ('{efidev}\t/boot/efi\t{efiopt}\n') + + + +#/** +# ogSetLinuxName int_ndisk int_nfilesys [str_name] +#@brief Establece el nombre del equipo en los ficheros hostname y hosts. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@param str_name nombre asignado (opcional) +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#@note Si no se indica nombre, se asigna un valor por defecto. +#*/ ## + + + +#/** +# ogCleanLinuxDevices int_ndisk int_nfilesys +#@brief Limpia los dispositivos del equipo de referencia. Interfaz de red ... +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#*/ ## +#ogCleanLinuxDevices (1, 1) +def ogCleanLinuxDevices (disk, par): + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: return None + + # Eliminar fichero de configuración de udev para dispositivos fijos de red. + if os.path.exists (f'{mntdir}/etc/udev/rules.d/70-persistent-net.rules'): + os.unlink (f'{mntdir}/etc/udev/rules.d/70-persistent-net.rules') + # Eliminar fichero resume (estado previo de hibernación) utilizado por el initrd scripts-premount + if os.path.exists (f'{mntdir}/etc/initramfs-tools/conf.d/resume'): + os.unlink ( f'{mntdir}/etc/initramfs-tools/conf.d/resume') + +#/** +# ogGrubAddOgLive num_disk num_part [ timeout ] [ offline ] +#@brief Crea entrada de menu grub para ogclient, tomando como paramentros del kernel los actuales del cliente. +#@param 1 Numero de disco +#@param 2 Numero de particion +#@param 3 timeout Segundos de espera para iniciar el sistema operativo por defecto (opcional) +#@param 4 offline configura el modo offline [offline|online] (opcional) +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND No existe kernel o initrd en cache. +#@exception OG_ERR_NOTFOUND No existe archivo de configuracion del grub. +# /// FIXME: Solo para el grub instalado en MBR por Opengnsys, ampliar para más casos. +#*/ ## + +#/** +# ogGrubHidePartitions num_disk num_part +#@brief ver ogBootLoaderHidePartitions +#@see ogBootLoaderHidePartitions +#*/ ## + +#/** +# ogBurgHidePartitions num_disk num_part +#@brief ver ogBootLoaderHidePartitions +#@see ogBootLoaderHidePartitions +#*/ ## + +#/** +# ogBootLoaderHidePartitions num_disk num_part +#@brief Configura el grub/burg para que oculte las particiones de windows que no se esten iniciando. +#@param 1 Numero de disco +#@param 2 Numero de particion +#@param 3 Numero de disco de la partición de datos (no ocultar) +#@param 4 Numero de particion de datos (no ocultar) +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception No existe archivo de configuracion del grub/burg. +#*/ + +#/** +# ogGrubDeleteEntry num_disk num_part num_disk_delete num_part_delete +#@brief ver ogBootLoaderDeleteEntry +#@see ogBootLoaderDeleteEntry +#*/ + +#/** +# ogBurgDeleteEntry num_disk num_part num_disk_delete num_part_delete +#@brief ver ogBootLoaderDeleteEntry +#@see ogBootLoaderDeleteEntry +#*/ + +#/** +# ogRefindDeleteEntry num_disk_delete num_part_delete +#@brief ver ogBootLoaderDeleteEntry +#@see ogBootLoaderDeleteEntry +#*/ + +#/** +# ogBootLoaderDeleteEntry num_disk num_part num_part_delete +#@brief Borra en el grub las entradas para el inicio en una particion. +#@param 1 Numero de disco donde esta el grub +#@param 2 Numero de particion donde esta el grub +#@param 3 Numero del disco del que borramos las entradas +#@param 4 Numero de la particion de la que borramos las entradas +#@note Tiene que ser llamada desde ogGrubDeleteEntry, ogBurgDeleteEntry o ogRefindDeleteEntry +#@return (nada) +#@exception OG_ERR_FORMAT Use ogGrubDeleteEntry or ogBurgDeleteEntry. +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND No existe archivo de configuracion del grub. +#*/ ## + +#/** +# ogBurgInstallMbr int_disk_GRUBCFG int_partition_GRUBCFG +#@param bolean_Check_Os_installed_and_Configure_2ndStage true | false[default] +#@brief Instala y actualiza el gestor grub en el MBR del disco duro donde se encuentra el fichero grub.cfg. Admite sistemas Windows. +#@param int_disk_SecondStage +#@param int_part_SecondStage +#@param bolean_Check_Os_installed_and_Configure_2ndStage true | false[default] +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Partición no soportada +#*/ ## + +#/** +# ogGrubDefaultEntry int_disk_GRUGCFG int_partition_GRUBCFG int_disk_default_entry int_npartition_default_entry +#@brief ver ogBootLoaderDefaultEntry +#@see ogBootLoaderDefaultEntry +#*/ ## + +#/** +# ogBurgDefaultEntry int_disk_BURGCFG int_partition_BURGCFG int_disk_default_entry int_npartition_default_entry +#@brief ver ogBootLoaderDefaultEntry +#@see ogBootLoaderDefaultEntry +#*/ ## + + +#/** +# ogRefindDefaultEntry int_disk_default_entry int_npartition_default_entry +#@brief ver ogBootLoaderDefaultEntry +#@see ogBootLoaderDefaultEntry +#*/ ## + +#/** +# ogBootLoaderDefaultEntry int_disk_CFG int_partition_CFG int_disk_default_entry int_npartition_default_entry +#@brief Configura la entrada por defecto de Burg +#@param int_disk_SecondStage +#@param int_part_SecondStage +#@param int_disk_default_entry +#@param int_part_default_entry +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Partición errónea o desconocida (ogMount). +#@exception OG_ERR_OUTOFLIMIT Param $3 no es entero. +#@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: burg.cfg. +#*/ ## + +#/** +# ogGrubOgliveDefaultEntry num_disk num_part +#@brief ver ogBootLoaderOgliveDefaultEntry +#@see ogBootLoaderOgliveDefaultEntry +#*/ ## + +#/** +# ogBurgOgliveDefaultEntry num_disk num_part +#@brief ver ogBootLoaderOgliveDefaultEntry +#@see ogBootLoaderOgliveDefaultEntry +#*/ ## + + +#/** +# ogRefindOgliveDefaultEntry +#@brief ver ogBootLoaderOgliveDefaultEntry +#@see ogBootLoaderOgliveDefaultEntry +#*/ ## + + +#/** +# ogBootLoaderOgliveDefaultEntry +#@brief Configura la entrada de ogLive como la entrada por defecto de Burg. +#@param int_disk_SecondStage +#@param int_part_SecondStage +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Partición errónea o desconocida (ogMount). +#@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: burg.cfg. +#@exception OG_ERR_NOTFOUND Entrada de OgLive no encontrada en burg.cfg. +#*/ ## + + +#/** +# ogGrubSecurity int_disk_GRUBCFG int_partition_GRUBCFG [user] [password] +#@brief Configura grub.cfg para que sólo permita editar entrada o acceder a línea de comandos al usuario especificado +#@param int_disk_SecondStage +#@param int_part_SecondStage +#@param user (default root) +#@param password (default "", no puede entrar) +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar (ogMount). +#@exception OG_ERR_NOTFOUND No encuentra archivo de configuración del grub. +#*/ ## + + +#/** +# ogGrubSetTheme num_disk num_part str_theme +#@brief ver ogBootLoaderSetTheme +#@see ogBootLoaderSetTheme +#*/ ## + +#/** +# ogBurgSetTheme num_disk num_part str_theme +#@brief ver ogBootLoaderSetTheme +#@see ogBootLoaderSetTheme +#*/ ## + + +#/** +# ogRefindSetTheme str_theme +#@brief ver ogBootLoaderSetTheme +#@see ogBootLoaderSetTheme +#*/ ## + + +#/** +# ogBootLoaderSetTheme +#@brief asigna un tema al BURG +#@param int_disk_SecondStage +#@param int_part_SecondStage +#@param str_theme_name +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Partición errónea o desconocida (ogMount). +#@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: grub.cfg burg.cfg refind.conf. +#@exception OG_ERR_NOTFOUND Entrada deltema no encontrada en burg.cfg. +#@exception OG_ERR_NOTFOUND Fichero de configuración del tema no encontrado: theme.conf (sólo refind). +#@note El tema debe situarse en OGLIB/BOOTLOADER/themes +#*/ ## + +#/** +# ogGrubSetAdminKeys num_disk num_part str_theme +#@brief ver ogBootLoaderSetTheme +#@see ogBootLoaderSetTheme +#*/ ## + +#/** +# ogBurgSetAdminKeys num_disk num_part str_bolean +#@brief ver ogBootLoaderSetAdminKeys +#@see ogBootLoaderSetAdminKeys +#*/ ## + + + +#/** +# ogBootLoaderSetAdminKeys +#@brief Activa/Desactica las teclas de administracion +#@param int_disk_SecondStage +#@param int_part_SecondStage +#@param Boolean TRUE/FALSE +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Partición errónea o desconocida (ogMount). +#@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: grub.cfg burg.cfg. +#@exception OG_ERR_NOTFOUND Entrada deltema no encontrada en burg.cfg. +#*/ ## + + + +#/** +# ogGrubSetTimeOut num_disk num_part int_timeout_seconds +#@brief ver ogBootLoaderSetTimeOut +#@see ogBootLoaderSetTimeOut +#*/ ## + +#/** +# ogBurgSetTimeOut num_disk num_part str_bolean +#@brief ver ogBootLoaderSetTimeOut +#@see ogBootLoaderSetTimeOut +#*/ ## + + +#/** +# ogRefindSetTimeOut int_timeout_second +#@brief ver ogBootLoaderSetTimeOut +#@see ogBootLoaderSetTimeOut +#*/ ## + +#/** +# ogBootLoaderSetTimeOut +#@brief Define el tiempo (segundos) que se muestran las opciones de inicio +#@param int_disk_SecondStage +#@param int_part_SecondStage +#@param int_timeout_seconds +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Partición errónea o desconocida (ogMount). +#@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: grub.cfg burg.cfg. +#@exception OG_ERR_NOTFOUND Entrada deltema no encontrada en burg.cfg. +#*/ ## + + +#/** +# ogGrubSetResolution num_disk num_part int_resolution +#@brief ver ogBootLoaderSetResolution +#@see ogBootLoaderSetResolution +#*/ ## + +#/** +# ogBurgSetResolution num_disk num_part str_bolean +#@brief ver ogBootLoaderSetResolution +#@see ogBootLoaderSetResolution +#*/ ## + + + +#/** +# ogBootLoaderSetResolution +#@brief Define la resolucion que usuara el thema del gestor de arranque +#@param int_disk_SecondStage +#@param int_part_SecondStage +#@param str_resolution (Opcional) +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Partición errónea o desconocida (ogMount). +#@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: grub.cfg burg.cfg. +#*/ ## + + + + +#/** +# ogBootLoaderSetResolution +#@brief Define la resolucion que usuara el thema del gestor de arranque +#@param int_resolution1 +#@param int_resolution2 (Opcional) +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Partición errónea o desconocida (ogMount). +#@exception OG_ERR_NOTFOUND Fichero de configuración no encontrado: grub.cfg burg.cfg. +#*/ ## + +# ogRefindInstall bool_autoconfig +#@brief Instala y actualiza el gestor rEFInd en la particion EFI +#@param bolean_Check__auto_config true | false[default] +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND No se encuentra la partición ESP. +#@exception OG_ERR_NOTFOUND No se encuentra shimx64.efi.signed. +#@exception OG_ERR_NOTFOUND No se encuentra refind-install o refind en OGLIB +#@exception OG_ERR_PARTITION No se puede montar la partición ESP. +#@note Refind debe estar instalado en el ogLive o compartido en OGLIB +#*/ ## + +#/** +# ogGrub4dosInstallMbr int_ndisk +#@brief Genera un nuevo Codigo de arranque en el MBR del disco indicado, compatible con los SO tipo Windows, Linux. +#@param int_ndisk nº de orden del disco +#@param int_ndisk nº de orden del particion +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Tipo de partición desconocido o no se puede montar. +#@exception OG_ERR_NOTBIOS Equipo no firmware BIOS legacy +#@exception OG_ERR_NOMSDOS Disco duro no particioniado en modo msdos +#@exception OG_ERR_NOTWRITE Particion no modificable. +#*/ ## diff --git a/client/lib/python3/CacheLib.py b/client/lib/python3/CacheLib.py new file mode 100644 index 0000000..1c4357c --- /dev/null +++ b/client/lib/python3/CacheLib.py @@ -0,0 +1,369 @@ +import os +import re +import subprocess +import shutil +import sys +import platform + +import ogGlobals +import SystemLib +import DiskLib +import FileSystemLib +import CacheLib + +#/** +# ogCreateCache [int_ndisk] int_partsize +#@brief Define la caché local, por defecto en partición 4 del disco 1. +#@param int_ndisk numero de disco donde crear la cache, si no se indica es el 1 por defecto +#@param int_npart número de partición (opcional, 4 por defecto) +#@param int_partsize tamaño de la partición (en KB) +#@return (nada, por determinar) +#@exception OG_ERR_FORMAT formato incorrecto. +#@note Requisitos: sfdisk, parted, awk, sed +#@warning El tamaño de caché debe estar entre 50 MB y la mitad del disco. +#@warning La caché no puede solaparse con las particiones de datos. +#*/ ## +def ogCreateCache (ndsk=1, part=4, sizecache=0): + if not sizecache: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '') + return None + sizecache = int (sizecache) + + DISK = DiskLib.ogDiskToDev (ndsk) + if not DISK: return None + + # PATCH Para discos nvme la particion debe ser p1, p2, etc...en lugar de 1,2, sino falla sfdisk + NVME_PREFIX = '' + if 'nvme' in DISK: + NVME_PREFIX = 'p' + + END = DiskLib.ogGetLastSector (ndsk) + SIZE = 2 * sizecache +# Inicio partición cache según el disco tenga sectores de 4k o menores + IOSIZE = 0 + fdisk_out = subprocess.run (['fdisk', '-l', DISK], capture_output=True, text=True).stdout + for l in fdisk_out.splitlines(): + items = l.split() + if len(items) < 4: continue + if 'I/O' == items[0]: + IOSIZE = int (items[3]) + break + START = 0 + if 4096 == IOSIZE: + END -= 8192 + START = END - SIZE + 2048 - (END-SIZE)%2048 + else: + START = END - SIZE + 1 + + ENDPREVPART = None + i = 1 + while True: + prev_part = part - i + if prev_part <= 0: break + ENDPREVPART = DiskLib.ogGetLastSector (ndsk, prev_part) + print (f'nati got endprevpart ({ENDPREVPART})') + if ENDPREVPART: break + i += 1 + if not ENDPREVPART: + print (f'nati no endprevpart, assuming 0') + ENDPREVPART=0 + #SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, ndsk) + #return None +# Error si tamaño no está entre límites permitidos o si se solapa con la partición anterior. + MINSIZE = 25000 + MAXSIZE = END + if SIZE < MINSIZE or SIZE > MAXSIZE or START < ENDPREVPART: + print (f'nati size ({SIZE}) < minsize ({MINSIZE}) or size > maxsize ({MAXSIZE}) or start ({START}) < endprevpart ({ENDPREVPART})') + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, ndsk) + return None + +# Desmontar todos los sistemas de archivos del disco. + FileSystemLib.ogUnmountAll (ndsk) +# Definir particiones y notificar al kernel. +# En el caso de ser disco GPT, de momento se borra la particion y se vuelve a crear, +# por lo que se pierden los datos. + pttype = DiskLib.ogGetPartitionTableType (ndsk) + print (f'nati pttype ({pttype})') + if not pttype: + pttype = 'MSDOS' + DiskLib.ogCreatePartitionTable (ndsk, pttype) + + get_ptt = DiskLib.ogGetPartitionTableType (ndsk) + print (f'nati get_ptt ({get_ptt})') + if 'GPT' == get_ptt: + # Si la tabla de particiones no es valida, volver a generarla. + if subprocess.run (['sgdisk', '-p', DISK]).returncode: + subprocess.run (['gdisk', DISK], input='2\nw\nY\n', text=True) + # Si existe la cache se borra previamente + if ogFindCache(): ogDeleteCache() + # Capturamos el codigo de particion GPT para cache + # PATCH - Cuando es GPT, la particion con codigo CACHE (CA00) no existe y no puede crearse, se cambia por LINUX (8300) + ID = DiskLib.ogTypeToId ('LINUX', 'GPT') + print (f'nati ID ({ID})') + subprocess.run (['sgdisk', DISK, f'-n{part}:{START}:{END}', f'-c{part}:CACHE', f'-t{part}:{ID}']) + elif 'MSDOS' == get_ptt: + # Si la tabla de particiones no es valida, volver a generarla. + if subprocess.run (['parted', '-s', DISK, 'print']).returncode: + subprocess.run (['fdisk', DISK], input='w\n', text=True) + # Definir particiones y notificar al kernel. + ID = DiskLib.ogTypeToId ('CACHE', 'MSDOS') + print (f'nati ID ({ID})') + # Salvamos la configuración de las particiones e incluimos la cache. + tmp = subprocess.run (['sfdisk', '--dump', DISK], capture_output=True, text=True).stdout.splitlines() + tmp = [ x for x in tmp if f'{DISK}{part}' not in x ] + tmp.append (f'{DISK}{NVME_PREFIX}{part} : start= {START}, size= {SIZE}, Id={ID}') + # Ordenamos las líneas de los dispositivos + UNIT = [ x for x in tmp if 'unit' in x ][0] + tmp = sorted ([ x for x in tmp if re.match ('^/dev', x) ]) + tmp = [UNIT, ''] + tmp + # Guardamos nueva configuración en el disco. + i = '\n'.join(tmp) + print (f'nati i ({i})') + subprocess.run (['sfdisk', '--no-reread', DISK], input=i, text=True) +# Actualiza la tabla de particiones en el kernel. + DiskLib.ogUpdatePartitionTable() + + + +#/** +# ogDeleteCache +#@brief Elimina la partición de caché local. +#@return (nada, por determinar) +#@exception OG_ERR_FORMAT formato incorrecto. +#@note Requisitos: fdisk, sgdisk, partprobe +#*/ ## +def ogDeleteCache(): + cachepart = ogFindCache() + if not cachepart: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE) + return None + + ndisk, npart = cachepart.split() + disk = DiskLib.ogDiskToDev (ndisk) + +# Desmontar todos los sistemas de archivos del disco. + FileSystemLib.ogUnmountAll (ndisk) + + ptt = DiskLib.ogGetPartitionTableType (ndisk) + if 'GPT' == ptt: + # Si la tabla de particiones no es valida, volver a generarla. + if subprocess.run (['sgdisk', '-p', disk]).returncode: + subprocess.run (['gdisk', disk], input='2\nw\nY\n', text=True) + subprocess.run (['sgdisk', disk, f'-d{npart}']) + elif 'MSDOS' == ptt: + # Si la tabla de particiones no es valida, volver a generarla. + if subprocess.run (['parted', '-s', disk, 'print']).returncode: + subprocess.run (['fdisk', disk], input='w', text=True) + # Eliminar la partición de caché. + subprocess.run (['fdisk', disk], input=f'd\n{npart}\nw', text=True) +# Borrar etiqueta de la caché. + if os.path.exists ('/dev/disk/by-label/CACHE'): + os.unlink ('/dev/disk/by-label/CACHE') +#Actualiza la tabla de particiones en el kernel. + DiskLib.ogUpdatePartitionTable() + +#/** +# ogFindCache +#@brief Detecta la partición caché local. +#@param No requiere parametros +#@return int_ndisk int_npart - devuelve el par nº de disco-nº de partición . +#@warning Si no hay cache no devuelve nada +#*/ ## +def ogFindCache(): + # Obtener el dispositivo del sistema de archivos etiquetado como "CACHE". + PART = subprocess.run (['blkid', '-L', 'CACHE'], capture_output=True, text=True).stdout.strip() + + # En discos nvme con particiones GPT la partición se detecta usando el tag PARTLABEL + if not PART: + out = subprocess.run (['blkid', '-t', 'PARTLABEL=CACHE'], capture_output=True, text=True).stdout.strip() + PART = out.split (':')[0] + + # Si no se detecta, obtener particiones marcadas de tipo caché en discos MSDOS. + if not PART: + out = subprocess.run (['sfdisk', '-l'], capture_output=True, text=True).stdout.splitlines() + for l in out: + elems = l.split (maxsplit=5) + if 6 > len (elems): continue + if 'ca' in elems[5] or 'a7' in elems[5]: + PART=elems[0] + break + + # Por último revisar todos los discos GPT y obtener las particiones etiquetadas como caché. + if not PART: + PART = '' + for d in DiskLib.ogDiskToDev(): + out = subprocess.run (['sgdisk', '-p', d], capture_output=True, text=True).stdout.splitlines() + for l in out: + elems = l.split (maxsplit=6) + if 7 > len (elems): continue + if 'CACHE' in elems[6]: + p = 'p' if 'nvme' in d else '' + PART += f' {d}{p}{elems[0]}' + + if not PART: return + return DiskLib.ogDevToDisk (PART.split()[0]) # usar la 1ª partición encontrada. + + +#/** +# ogFormatCache +#@brief Formatea el sistema de ficheros para la caché local. +#@return (por determinar) +#@warning Prueba con formato Reiser. +#@attention +#@note El sistema de archivos de la caché se queda montado. +#*/ ## +def ogFormatCache(): + cachepart = ogFindCache() + if cachepart is None: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE) + return + + cachepart = cachepart.split() + disk = DiskLib.ogDiskToDev (cachepart[0], cachepart[1]) + if not disk: return + + ogUnmountCache() + options = "extent,large_file" + if re.match("^5", platform.release()): + options += ",uninit_bg,^metadata_csum,^64bit" + + try: + subprocess.run(["mkfs.ext4", "-q", "-F", disk, "-L", "CACHE", "-O", options], check=True) + except subprocess.CalledProcessError as e: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, "CACHE") + return + + # Crear estructura básica. + mntdir = ogMountCache() + j = '/'.join ([mntdir, ogGlobals.OGIMG]) ## os.path.join doesn't work: "If a segment […] is an absolute path, all previous segments are ignored" + #print (f'cucu mntdir ({mntdir}) OGIMG ({ogGlobals.OGIMG}) j ({j})') + os.makedirs (j, exist_ok=True) + + # Incluir kernel e Initrd del ogLive + ## como lo llamo sin especificar el path entero? + #subprocess.run (['scripts/updateBootCache.py']) ## TODO + + +#/** +# ogGetCacheSize +#@brief Devuelve el tamaño definido para la partición de caché. +#@return int_partsize tamaño de la partición (en KB) +#@exception OG_ERR_PARTITION No existe partición de caché. +#*/ ## +def ogGetCacheSize(): + cachepart = ogFindCache() + if cachepart is None: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE) + return None + + disk, par = cachepart.split() + return DiskLib.ogGetPartitionSize (disk, par) + +#/** +# ogGetCacheSpace +#@brief Devuelve el espacio de disco disponible para la partición de caché. +#@return int_size tamaño disponible (en KB) +#@note El espacio disponible es el que hay entre el límite superior de la partición 3 del disco 1 y el final de dicho disco, y no puede ser superior a la mitad de dicho disco. +#*/ ## +def ogGetCacheSpace(): + cachepart = ogFindCache() + if not cachepart: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE) + return None + cachepart = cachepart.split() + + disk = DiskLib.ogDiskToDev (cachepart[0]) + if not disk: + return None + + sectors = 0 + disk_bn = os.path.basename (disk) + with open ('/proc/partitions', 'r') as fd: + proc_parts = fd.read() + for l in proc_parts.splitlines(): + items = l.split() + if len(items) < 4: continue + if items[3] == disk_bn: + sectors = 2 * int (items[2]) + if not sectors: return None + + sfdisk_out = subprocess.run (['sfdisk', '-g', disk], capture_output=True, text=True).stdout + cyls = int (sfdisk_out.split()[1]) + sectors = sectors/cyls * cyls - 1 + + ## the original code has a hard dependency on the existence of a third partition + ## if the disk has sda1, sda2 and sda4, the code fails. + ## this is an improved version + endpart3 = 0 + for trypart in [3, 2, 1]: + sfdisk_out = subprocess.run (['sfdisk', '-uS', '-l', disk], capture_output=True, text=True).stdout + for l in sfdisk_out.splitlines(): + items = l.split() + if len(items) < 6: continue + if f'{disk}{trypart}' == items[0]: + endpart3 = int (items[2]) + break + if endpart3: break + if not endpart3: return None + +# Mostrar espacio libre en KB (1 KB = 2 sectores) + if endpart3 > sectors // 2: + return (sectors - endpart3) // 2 + else: + return sectors // 4 + + +#/** +# ogMountCache +#@brief Monta la partición Cache y exporta la variable $OGCAC +#@param sin parametros +#@return path_mountpoint - Punto de montaje del sistema de archivos de cache. +#@warning Salidas de errores no determinada +#*/ ## +def ogMountCache(): + c = ogFindCache() + if not c: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE) + return None + + c = c.split() + m = FileSystemLib.ogMountFs (c[0], c[1]) + if not m: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE) + return None + return m + + +#/** +# ogUnmountCache +#@brief Desmonta la particion Cache y elimina la variable $OGCAC +#@param sin parametros +#@return nada +#@warning Salidas de errores no determinada +#*/ ## +def ogUnmountCache(): + cachepart = ogFindCache() + if cachepart is None: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, ogGlobals.lang.MSG_NOCACHE) + return + + cachepart = cachepart.split() + if not FileSystemLib.ogIsMounted (cachepart[0], cachepart[1]): return True + FileSystemLib.ogUnmountFs (cachepart[0], cachepart[1]) + + # Eliminar el enlace simbólico de /mnt/ParticiónCache. + dev = DiskLib.ogDiskToDev (cachepart[0], cachepart[1]) + dev = dev.replace ('dev', 'mnt') + if os.path.exists (dev): os.remove (dev) + + +#/** +# initCache +#@brief Simplemente llama al script initCache +#@brief Es necesario tener una función para poder pasársela a ogExecAndLog +#@param los mismos parametros que initCache +#@return lo mismo que devuelve initCache +#*/ ## +def initCache (*args): + p = subprocess.run (['/opt/opengnsys/images/nati/client/shared/scripts/initCache.py'] + list(args)) + return p.returncode diff --git a/client/lib/python3/DiskLib.py b/client/lib/python3/DiskLib.py new file mode 100644 index 0000000..5b95b05 --- /dev/null +++ b/client/lib/python3/DiskLib.py @@ -0,0 +1,1424 @@ +#/** +#@file DiskLib.py +#@brief Librería o clase Disk +#@class Disk +#@brief Funciones para gestión de discos y particiones. +#@warning License: GNU GPLv3+ +#*/ + +import filecmp +import subprocess +import shutil +import os +import re +import stat +from pathlib import Path + +import ogGlobals +import SystemLib +import CacheLib +import FileSystemLib +import InventoryLib + +# Función ficticia para lanzar parted con timeout, evitando cuelgues del programa. +def parted(*args): + parted_path = shutil.which("parted") + if parted_path: + try: + result = subprocess.run( + [parted_path] + list(args), + timeout=3, + capture_output=True, + text=True + ) + return result.stdout + except subprocess.TimeoutExpired: + return "Error: Command 'parted' timed out" + else: + return "Error: 'parted' command not found" + + +#/** +# ogCreatePartitions int_ndisk str_parttype:int_partsize ... +#@brief Define el conjunto de particiones de un disco. +#@param int_ndisk nº de orden del disco +#@param str_parttype mnemónico del tipo de partición +#@param int_partsize tamaño de la partición (en KB) +#@return (nada, por determinar) +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND disco o partición no detectado (no es un dispositivo). +#@exception OG_ERR_PARTITION error en partición o en tabla de particiones. +#@attention El nº de partición se indica por el orden de los párametros \c parttype:partsize +#@attention Pueden definirse particiones vacías de tipo \c EMPTY +#@attention No puede definirse partición de cache y no se modifica si existe. +#@note Requisitos: sfdisk, parted, partprobe, awk +#@todo Definir atributos (arranque, oculta) y tamaños en MB, GB, etc. +#*/ ## +def ogCreatePartitions (disk, parts): + ND = disk + DISK = ogDiskToDev (ND) + if not DISK: return None + + PTTYPE = ogGetPartitionTableType (disk) + if not PTTYPE: PTTYPE = 'MSDOS' # Por defecto para discos vacíos. + + if 'GPT' == PTTYPE: + return ogCreateGptPartitions (disk, parts) + elif 'MSDOS' != PTTYPE: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, PTTYPE) + return None + + # Se calcula el ultimo sector del disco (total de sectores usables) + SECTORS = ogGetLastSector (disk) + + # Se recalcula el nº de sectores del disco si existe partición de caché. + CACHESIZE = 0 + CACHEPART = CacheLib.ogFindCache() + if CACHEPART: + cache_disk, cache_part = CACHEPART.split() + if ND == cache_disk: + CACHESIZE = int (CacheLib.ogGetCacheSize()) * 2 + # Sector de inicio (la partición 1 empieza en el sector 63). + IODISCO = ogDiskToDev (disk) + IOSIZE = 0 + fdisk_out = subprocess.run (['fdisk', '-l', IODISCO], capture_output=True, text=True).stdout + for l in fdisk_out.splitlines(): + if 'I/O' not in l: continue + items = l.split() + if len(items) < 4: continue + IOSIZE = items[3] + break + + if '4096' == IOSIZE: + START = 4096 + SECTORS -= 8192 + if CACHESIZE: + SECTORS = SECTORS - CACHESIZE + 2048 - (SECTORS - CACHESIZE) % 2048 - 1 + else: + START = 63 + if CACHESIZE: + SECTORS -= CACHESIZE + + PART = 1 + print (f'START ({START}) SECTORS ({SECTORS}) PART ({PART})') + + sfdisk_input = 'unit: sectors\n\n' + NVME_PREFIX = 'p' if 'nvme' in DISK else '' + for p in parts: + # Conservar los datos de la partición de caché. + if f'{ND} {PART}' == CACHEPART and CACHESIZE: + sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={SECTORS+1}, size={CACHESIZE}, Id=ca\n' + PART += 1 + + # Leer formato de cada parámetro - Tipo:Tamaño + TYPE, SIZE = p.split (':') + try: + SIZE = int (SIZE) + except ValueError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, SIZE) + return None + + # Obtener identificador de tipo de partición válido. + ID = ogTypeToId (TYPE, 'MSDOS') + if 'CACHE' == TYPE or not ID: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, TYPE) + return None + # Comprobar tamaño numérico y convertir en sectores de 512 B. + SIZE *= 2 + # Comprobar si la partición es extendida. + EXTSTART = EXTSIZE = 0 + if 5 == ID: + if PART > 4: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '') + return None + # El inicio de la primera partición logica es el de la extendida más 4x512 + EXTSTART = START+2048 + EXTSIZE = SIZE-2048 + # Incluir particiones lógicas dentro de la partición extendida. + if 5 == PART: + if not EXTSTART: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '') + return None + START = EXTSTART + SECTORS = EXTSTART+EXTSIZE + + # Generar datos para la partición. + # En el caso de que la partición sea EMPTY no se crea nada + if 'EMPTY' != TYPE: + sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={START}, size={SIZE}, Id={ID}\n' + + START += SIZE + + # Error si se supera el nº total de sectores. + if '4096' == IOSIZE and PART > 4: + START += 2048 + if START > SECTORS: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{START//2} > {SECTORS//2}') + return None + PART += 1 + + # Si no se indican las 4 particiones primarias, definirlas como vacías, conservando la partición de caché. + while PART <= 4: + if f'{ND} {PART}' == CACHEPART and CACHESIZE: + sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start={SECTORS+1}, size={CACHESIZE}, Id=ca\n' + else: + sfdisk_input += f'{DISK}{NVME_PREFIX}{PART} : start=0, size=0, Id=0\n' + PART += 1 + # Si se define partición extendida sin lógicas, crear particion 5 vacía. + if 5 == PART and EXTSTART: + sfdisk_input += f'{DISK}5 : start={EXTSTART}, SIZE={EXTSIZE}, Id=0\n' + + # Desmontar los sistemas de archivos del disco antes de realizar las operaciones. + FileSystemLib.ogUnmountAll (ND) + if CACHESIZE: CacheLib.ogUnmountCache() + + # Si la tabla de particiones no es valida, volver a generarla. + ogCreatePartitionTable (ND) + + # Definir particiones y notificar al kernel. + #print (f'nati: about to run sfdisk: ({sfdisk_input})') + p = subprocess.run (['sfdisk', DISK], input=sfdisk_input, capture_output=True, text=True) + #print (f'nati: rc ({p.returncode}) stdout ({p.stdout}) stderr ({p.stderr})') + subprocess.run (['partprobe', DISK]) + if CACHESIZE: CacheLib.ogMountCache() + return True + + +#/** +# ogCreateGptPartitions int_ndisk str_parttype:int_partsize ... +#@brief Define el conjunto de particiones de un disco GPT +#@param int_ndisk nº de orden del disco +#@param str_parttype mnemónico del tipo de partición +#@param int_partsize tamaño de la partición (en KB) +#@return (nada, por determinar) +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND disco o partición no detectado (no es un dispositivo). +#@exception OG_ERR_PARTITION error en partición o en tabla de particiones. +#@attention El nº de partición se indica por el orden de los párametros \c parttype:partsize +#@attention Pueden definirse particiones vacías de tipo \c EMPTY +#@attention No puede definirse partición de caché y no se modifica si existe. +#@note Requisitos: sfdisk, parted, partprobe, awk +#@todo Definir atributos (arranque, oculta) y tamaños en MB, GB, etc. +#*/ ## +def ogCreateGptPartitions (disk, parts): + ND = disk + DISK = ogDiskToDev (ND) + if not DISK: return None + + # Se calcula el ultimo sector del disco (total de sectores usables) + SECTORS = ogGetLastSector (disk) + + # Se recalcula el nº de sectores del disco si existe partición de caché. + CACHESIZE = 0 + CACHEPART = CacheLib.ogFindCache() + if CACHEPART: + cache_disk, cache_part = CACHEPART.split() + if ND == cache_disk: + CACHESIZE = int (CacheLib.ogGetCacheSize()) * 2 + if CACHESIZE: + SECTORS -= CACHESIZE + + # Si el disco es GPT empieza en el sector 2048 por defecto, pero podria cambiarse + ALIGN = int (subprocess.run (['sgdisk', '-D', DISK], capture_output=True, text=True).stdout) + START = ALIGN + PART = 1 + print (f'START ({START}) SECTORS ({SECTORS}) PART ({PART})') + + # Leer parámetros con definición de particionado. + DELOPTIONS = [] + OPTIONS = [] + for p in parts: + # Conservar los datos de la partición de caché. + if f'{ND} {PART}' == CACHEPART and CACHESIZE: + PART += 1 + + # Leer formato de cada parámetro - Tipo:Tamaño + TYPE, SIZE = p.split (':') + try: + SIZE = int (SIZE) + except ValueError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, SIZE) + return None + + # Error si la partición es extendida (no válida en discos GPT). + if 'EXTENDED' == TYPE: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'EXTENDED') + return None + + # Comprobar si existe la particion actual, capturamos su tamaño para ver si cambio o no + PARTSIZE = ogGetPartitionSize (ND, PART) + # En sgdisk no se pueden redimensionar las particiones, es necesario borrarlas y volver a crealas + if PARTSIZE: + DELOPTIONS.append (f'-d{PART}') + + # Creamos la particion + # Obtener identificador de tipo de partición válido. + ID = ogTypeToId (TYPE, 'GPT') + if 'CACHE' == TYPE or not ID: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, TYPE) + return None + # Comprobar tamaño numérico y convertir en sectores de 512 B. + SIZE *= 2 + # SIZE debe ser múltiplo de ALIGN, si no gdisk lo mueve automáticamente. + SIZE = (SIZE // ALIGN) * ALIGN + + # Generar datos para la partición. + # En el caso de que la partición sea EMPTY no se crea nada + if 'EMPTY' != TYPE: + OPTIONS += [f'-n{PART}:{START}:+{SIZE}', f'-t{PART}:{ID}'] + + START += SIZE + + # Error si se supera el nº total de sectores. + if START > SECTORS: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{START//2} > {SECTORS//2}') + return None + + PART += 1 + + # Desmontar los sistemas de archivos del disco antes de realizar las operaciones. + FileSystemLib.ogUnmountAll (ND) + if CACHESIZE: CacheLib.ogUnmountCache() + + # Si la tabla de particiones no es valida, volver a generarla. + ogCreatePartitionTable (ND, 'GPT') + + # Definir particiones y notificar al kernel. + #print (f'nati: about to run sgdisk ({DELOPTIONS}) ({OPTIONS}) ({DISK})') + p = subprocess.run (['sgdisk'] + DELOPTIONS + OPTIONS + [DISK]) + #print (f'nati: rc ({p.returncode}) stdout ({p.stdout}) stderr ({p.stderr})') + subprocess.run (['partprobe', DISK]) + if CACHESIZE: CacheLib.ogMountCache() + return True + + +#/** +# ogCreatePartitionTable int_ndisk [str_tabletype] +#@brief Genera una tabla de particiones en caso de que no sea valida, si es valida no hace nada. +#@param int_ndisk nº de orden del disco +#@param str_tabletype tipo de tabla de particiones (opcional) +#@return (por determinar) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@note tabletype: { MSDOS, GPT }, MSDOS por defecto +#@note Requisitos: fdisk, gdisk, parted +#*/ ## +def ogCreatePartitionTable (disk, createptt=None): + DISK = ogDiskToDev (disk) + if not DISK: return None + + pttype = ogGetPartitionTableType (disk) or 'MSDOS' # Por defecto para discos vacíos. + createptt = createptt or pttype + CREATE = None + +# Si la tabla actual y la que se indica son iguales, se comprueba si hay que regenerarla. + if createptt == pttype: + if 'GPT' == pttype: + try: + result = subprocess.run (['sgdisk', '-p', DISK], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + if result.returncode: + CREATE = 'GPT' + except subprocess.CalledProcessError: + CREATE = 'GPT' + elif 'MSDOS' == pttype: + try: + result = subprocess.run (['parted', '-s', DISK, 'print'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + if result.returncode: + CREATE = 'MSDOS' + except subprocess.CalledProcessError: + CREATE = 'MSDOS' + else: + CREATE = createptt.upper() + +# Dependiendo del valor de CREATE, creamos la tabla de particiones en cada caso. + if 'GPT' == CREATE: + if 'MSDOS' == pttype: + subprocess.run (['sgdisk', '-go', DISK]) + else: + subprocess.run (['gdisk', DISK], input='2\nw\nY\n', text=True) + subprocess.run (['partprobe', DISK]) + elif 'MSDOS' == CREATE: + if 'GPT' == pttype: + subprocess.run (['sgdisk', '-Z', DISK]) + # Crear y borrar una partición para que la tabla se genere bien. + subprocess.run (['fdisk', DISK], input='o\nn\np\n\n\n\nd\n\nw', text=True) + subprocess.run (['partprobe', DISK]) + + return None + + +#/** +# ogDeletePartitionTable ndisk +#@brief Borra la tabla de particiones del disco. +#@param int_ndisk nº de orden del disco +#@return la informacion propia del fdisk +#*/ ## +def ogDeletePartitionTable (disk): + DISK = ogDiskToDev (disk) + if not DISK: return None + + PTTYPE = ogGetPartitionTableType (disk) + if 'GPT' == PTTYPE: + subprocess.run (['sgdisk', '--clear', DISK]) + elif 'MSDOS' == PTTYPE: + subprocess.run (['fdisk', DISK], input='o\nw', text=True) + return + +#/** +# ogDevToDisk path_device | LABEL="str_label" | UUID="str_uuid" +#@brief Devuelve el nº de orden de dicso (y partición) correspondiente al nombre de fichero de dispositivo o a la etiqueta o UUID del sistema de archivos asociado. +#@param path_device Camino del fichero de dispositivo. +#@param str_label etiqueta de sistema de archivos. +#@param str_uuid UUID de sistema de archivos. +#@return int_ndisk (para dispositivo de disco) +#@return int_ndisk int_npartition (para dispositivo de partición). +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Dispositivo no detectado. +#@note Solo se acepta en cada llamada 1 de los 3 tipos de parámetros. +#*/ ## +def ogDevToDisk(arg_dev): + CACHEFILE = "/var/cache/disks.cfg" + + if '=' in arg_dev: + # arg_dev is "FOO=bar" + cmd = None + if arg_dev.startswith("LABEL="): cmd = ['blkid', '-L', arg_dev[6:]] + elif arg_dev.startswith("PARTLABEL="): cmd = ['realpath', '/dev/disk/by-partlabel/'+arg_dev[11:]] + elif arg_dev.startswith("PARTUUID="): cmd = ['realpath', '/dev/disk/by-partuuid/'+arg_dev[10:]] + elif arg_dev.startswith("UUID="): cmd = ['blkid', '-U', arg_dev[5:]] + if not cmd: + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_FORMAT, arg_dev) + return + DEV = subprocess.run (cmd, capture_output=True, text=True).stdout.strip() + else: + # arg_dev is "/dev/something" + DEV = arg_dev + + if not os.path.exists(DEV): + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_NOTFOUND, arg_dev) + return + + # Error si no es fichero de bloques o directorio (para LVM). + m = os.stat (DEV, follow_symlinks=True).st_mode + if not stat.S_ISBLK (m) and not stat.S_ISDIR (m): + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_NOTFOUND, arg_dev) + return + + # Buscar en fichero de caché de discos. + PART = None + if os.path.exists(CACHEFILE): + with open(CACHEFILE, 'r') as f: + for line in f: + parts = line.strip().split(':') + if len(parts) == 2 and parts[1] == DEV: + PART = parts[0] + break + + if PART: return PART + + # Si no se encuentra, procesa todos los discos para devolver su nº de orden y de partición. + disks = ogDiskToDev() + n = 1 + for d in disks: + NVME_PREFIX = "p" if "nvme" in d else "" + if DEV.startswith(d): + return f"{n} {DEV[len(d) + len(NVME_PREFIX):]}" + n += 1 + + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_NOTFOUND, arg_dev) + return + +def _getAllDisks(): + ret = [] + all_disks = subprocess.run("lsblk -n -e 1,2 -x MAJ:MIN 2>/dev/null || lsblk -n -e 1,2", shell=True, capture_output=True, text=True).stdout.splitlines() + for line in all_disks: + parts = line.split() + if parts[5] == "disk": + parts[0].replace ('!', '/') + ret.append(f"/dev/{parts[0]}") + return ret + +def _getAllVolGroups(): + vgs = subprocess.run(['vgs', '-a', '--noheadings'], capture_output=True, text=True).stdout.splitlines() + ret = [f"/dev/{line.split()[0]}" for line in vgs] + return ret + +def _getMPath(): + ret = alldisks2remove = [] + try: + mpath = subprocess.run(['multipath', '-l', '-v', '1'], capture_output=True, text=True).stdout.splitlines() + ret = [f"/dev/mapper/{line.split()[0]}" for line in mpath] + for line in subprocess.getoutput("multipath -ll").splitlines(): + if line.split()[5] == "ready": + alldisks2remove.append (f"/dev/{line.split()[2]}") + except FileNotFoundError: + pass + except subprocess.CalledProcessError: + pass + return ret, alldisks2remove + +def _getAllZFSVols(): + zfsvols = subprocess.run(['blkid'], capture_output=True, text=True).stdout.splitlines() + return [line.split(":")[0] for line in zfsvols if "zfs" in line] + +#/** +# ogDiskToDev [int_ndisk [int_npartition]] +#@brief Devuelve la equivalencia entre el nº de orden del dispositivo (dicso o partición) y el nombre de fichero de dispositivo correspondiente. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return Para 0 parametros: Devuelve los nombres de ficheros de los dispositivos sata/ata/usb linux encontrados. +#@return Para 1 parametros: Devuelve la ruta del disco duro indicado. +#@return Para 2 parametros: Devuelve la ruta de la particion indicada. +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Dispositivo no detectado. +#*/ ## +def ogDiskToDev (arg_disk=None, arg_part=None): + CACHEFILE = "/var/cache/disks.cfg" + + try: + if arg_part != None: + arg_part = int (arg_part) + except: + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_FORMAT, f"{arg_disk} {arg_part}") + return + + try: + if arg_disk != None: + arg_disk = int (arg_disk) + except: + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_FORMAT, arg_disk) + return + + # Borrar fichero de caché de configuración si hay cambios en las particiones. + proc_partitions = Path ('/proc/partitions').read_text() + tmp_partitions = Path ('/tmp/.partitions').read_text() if os.path.exists ('/tmp/.partitions') else '' + if proc_partitions != tmp_partitions: + # Guardar copia de las particiones definidas para comprobar cambios. + shutil.copy2('/proc/partitions', '/tmp/.partitions') + try: + os.remove(CACHEFILE) + except FileNotFoundError: + pass + + # Si existe una correspondencia con disco/dispositivo en el caché; mostrarlo y salir. + if arg_disk and os.path.exists (CACHEFILE): + with open(CACHEFILE, 'r') as f: + args_joined = ' '.join (map (str, filter (None, [arg_disk,arg_part]))) + for line in f: + parts = line.strip().split(':') + if len(parts) == 2 and parts[0] == args_joined: + return parts[1] + + # Continuar para detectar nuevos dispositivos. + + ALLDISKS = _getAllDisks() + + VOLGROUPS = _getAllVolGroups() + ALLDISKS += VOLGROUPS + + MPATH, ALLDISKS_to_remove =_getMPath() + for d in ALLDISKS_to_remove: + if d in ALLDISKS: ALLDISKS.remove (d) + + ZFSVOLS = _getAllZFSVols() + ALLDISKS += ZFSVOLS + + # No params: return all disks + if arg_disk is None: + return ALLDISKS + + # arg_disk is set: return it + if arg_part is None: + if arg_disk > len (ALLDISKS): + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_NOTFOUND, arg_disk) + return + disk = ALLDISKS[arg_disk-1] + if not os.path.exists(disk): + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_NOTFOUND, arg_disk) + return + # Actualizar caché de configuración y mostrar dispositivo. + with open(CACHEFILE, 'a') as f: + f.write(f"{arg_disk}:{disk}\n") + return disk + + # arg_disk and arg_part are set: there are several possibilities + if arg_disk > len (ALLDISKS): + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_NOTFOUND, arg_disk) + return + disk = ALLDISKS[arg_disk-1] + if not os.path.exists(disk): + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_NOTFOUND, arg_disk) + return + + # Plain partition + part = f"{disk}{arg_part}" + if os.path.exists(part): + # Actualizar caché de configuración y mostrar dispositivo. + with open(CACHEFILE, 'a') as f: + f.write(f"{arg_disk} {arg_part}:{part}\n") + return part + + # RAID/Multipath (tener en cuenta enlace simbólico). + part = f"{disk}p{arg_part}" + if os.path.exists(part) and stat.S_ISBLK (os.stat (part, follow_symlinks=True).st_mode): + # Actualizar caché de configuración y mostrar dispositivo. + with open(CACHEFILE, 'a') as f: + f.write(f"{arg_disk} {arg_part}:{part}\n") + return part + + part = "" + # Logical volume + if disk in VOLGROUPS: + lvscan = subprocess.run (['lvscan', '-a'], capture_output=True, text=True).stdout.splitlines() + i = 0 + for line in lvscan: + parts = line.split("'") + if parts[1].startswith(f"{disk}/") and i == arg_part: + part = parts[1] + break + i += 1 + + # ZFS volume + if disk in ZFSVOLS: + subprocess.run(["zpool", "import", "-f", "-R", "/mnt", "-N", "-a"]) + zpool = subprocess.run(['blkid', '-s', 'LABEL', '-o', 'value', disk], capture_output=True, text=True).stdout + zfs_list = subprocess.run(['zfs', 'list', '-Hp', '-o', 'name,canmount,mountpoint', '-r', zpool], capture_output=True, text=True).stdout.splitlines() + i = 0 + for line in zfs_list: + parts = line.split() + if parts[1] == "on" and parts[2] != "none": + if i == int(args[1]): + part = parts[0] + break + i += 1 + + if not part: + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_NOTFOUND, f"{arg_disk} {arg_part}") + return + + # Actualizar caché de configuración y mostrar dispositivo. + with open(CACHEFILE, 'a') as f: + f.write(f"{arg_disk} {arg_part}:{part}\n") + + return part + + +#/** +# ogGetDiskSize int_ndisk +#@brief Muestra el tamaño en KB de un disco. +#@param int_ndisk nº de orden del disco +#@return int_size - Tamaño en KB del disco. +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND disco o particion no detectado (no es un dispositivo). +#@note Requisitos: sfdisk, awk +#*/ ## +def ogGetDiskSize (disk): + DISK = ogDiskToDev (disk) + if not DISK: return None + + bn = os.path.basename (DISK) + SIZE = None + with open ('/proc/partitions', 'r') as fd: + while True: + l = fd.readline() + if not l: break + items = l.split() + if len(items) < 4: continue + if items[3] == bn: + SIZE = int (items[2]) + break + if not SIZE: + vgs_out = subprocess.run (['vgs', '--noheadings', '--units=B', '-o', 'dev_size', DISK], capture_output=True, text=True).stdout + items = vgs_out.split() + SIZE = int (items[0]) // 1024 + + return SIZE + + +#/** +# ogGetDiskType path_device +#@brief Muestra el tipo de disco (real, RAID, meta-disco, USB, etc.). +#@param path_device Dispositivo +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND disco no detectado o no es un dispositivo de bloques. +#@note Requisitos: udevadm +#*/ ## +def ogGetDiskType (dev): + DEV = os.path.basename (dev) + + bn = os.path.basename (DEV) + MAJOR = None + with open ('/proc/partitions', 'r') as fd: + while True: + l = fd.readline() + if not l: break + items = l.split() + if len(items) < 4: continue + if items[3] == bn: + MAJOR = items[0] + break + + TYPE = None + with open ('/proc/devices', 'r') as fd: + within_block_section = False + while True: + l = fd.readline() + if not l: break + + if 'Block' in l: + within_block_section = True + continue + if not within_block_section: + continue + + items = l.split() + if len(items) < 2: continue + if items[0] == MAJOR: + TYPE = items[1].upper() + break + + # Devolver mnemónico del driver de dispositivo. + if 'SD' == TYPE: + TYPE = 'DISK' + udevadm_out = subprocess.run (['udevadm', 'info', '-q', 'property', dev], capture_output=True, text=True).stdout + for l in udevadm_out.splitlines(): + if 'ID_BUS=usb' == l[0:10]: + TYPE = 'USB' + elif 'BLKEXT' == TYPE: + TYPE = 'NVM' + elif 'SR' == TYPE or TYPE.startswith ('IDE'): + TYPE = 'CDROM' # FIXME Comprobar discos IDE. + elif 'MD' == TYPE or TYPE.startswith ('CCISS'): + TYPE = 'RAID' + elif 'DEVICE-MAPPER' == TYPE: + TYPE = 'MAPPER' # FIXME Comprobar LVM y RAID. + + return TYPE + + +#/** +# ogGetEsp +#@brief Devuelve números de disco y partición para la partición EFI (ESP). +#*/ ## +def ogGetEsp(): + devices = subprocess.run (['blkid', '-o', 'device'], capture_output=True, text=True).stdout.splitlines() + devices.sort() + for d in devices: + # Previene error para /dev/loop0 + PART = ogDevToDisk (d) + if not PART: continue + + # En discos NVMe blkid devuelve una salida del tipo: + # >/dev/loop0 + # >/dev/nvme0n1 + # >/dev/nvme0n1p1 + # al analizar la particion nvme0n1, PART solo tiene un argumento y hace que ogGetPartitionId lance un error + if len (PART) > 1: + disk, par = PART.split() + if ogGetPartitionId (disk, par) == ogTypeToId ('EFI', 'GPT'): + return PART + return None + + +#/** +# ogGetLastSector int_ndisk [int_npart] +#@brief Devuelve el último sector usable del disco o de una partición. +#@param int_ndisk nº de orden del disco +#@param int_npart nº de orden de la partición (opcional) +#@return Último sector usable. +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o partición no corresponde con un dispositivo. +#@note Requisitos: sfdisk, sgdisk +#*/ ## +def ogGetLastSector (disk, par=None): + DISK = ogDiskToDev (disk) + if not DISK: return None + env = os.environ + env['LANG'] = 'C' + last = None + if par: + PART = ogDiskToDev (disk, par) + if not PART: return None + sgdisk_out = subprocess.run (['sgdisk', '-p', DISK], env=env, capture_output=True, text=True).stdout + for l in sgdisk_out.splitlines(): + items = l.split() + if len(items) < 3: continue + if str (par) != items[0]: continue + last = int (items[2]) + break + + else: + sgdisk_out = subprocess.run (['sgdisk', '-p', DISK], env=env, capture_output=True, text=True).stdout + for l in sgdisk_out.splitlines(): + if 'last usable sector' not in l: continue + items = l.split() + last = int (items[-1]) + + return last + + +#/** +# ogGetPartitionActive int_ndisk +#@brief Muestra que particion de un disco esta marcada como de activa. +#@param int_ndisk nº de orden del disco +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@note Requisitos: parted +#@todo Queda definir formato para atributos (arranque, oculta, ...). +#*/ ## +def ogGetPartitionActive (disk): + DISK = ogDiskToDev (disk) + if DISK is None: return + + if 'LANG' in os.environ: + lang = os.environ['LANG'] + + ret = None + os.environ['LANG'] = 'C' + lines = subprocess.run (['parted', '--script', '--machine', DISK, 'print'], capture_output=True, text=True).stdout.splitlines() + for line in lines: + parts = line.split (':') + if len (parts) < 6: continue + if 'boot' in parts[6]: + ret = parts[0] + break + + if lang is None: + del os.environ['LANG'] + else: + os.environ['LAMG'] = lang + + return ret + + +#/** +# ogGetPartitionId int_ndisk int_npartition +#@brief Devuelve el mnemónico con el tipo de partición. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return Identificador de tipo de partición. +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o partición no corresponde con un dispositivo. +#@note Requisitos: sfdisk +#*/ ## +def ogGetPartitionId (disk, par): + DISK = ogDiskToDev (disk) + if DISK is None: return + fsid = None + + pttype = ogGetPartitionTableType (disk) + if 'GPT' == pttype: + lines = subprocess.run (['sgdisk', '-p', DISK], capture_output=True, text=True).stdout.splitlines() + start_index = next (i for i, line in enumerate(lines) if 'Number' in line) + for l in lines[start_index:]: + idx, start, end, sz, sz_units, code, *rest = l.split() + if idx == str(par): + fsid = code + break + if fsid == '8300' and f'{disk} {par}' == CacheLib.ogFindCache(): + fsid = 'CA00' + elif 'MSDOS' == pttype: + fsid = subprocess.run (['sfdisk', '--part-type', DISK, par], capture_output=True, text=True).stdout.strip() + elif 'LVM' == pttype: + fsid = '10000' + elif 'ZPOOL' == pttype: + fsid = '10010' + + return fsid + + +#/** +# ogGetPartitionSize int_ndisk int_npartition +#@brief Muestra el tamano en KB de una particion determinada. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return int_partsize - Tamaño en KB de la partición. +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND disco o particion no detectado (no es un dispositivo). +#@note Requisitos: sfdisk, awk +#*/ ## +def ogGetPartitionSize (disk, par): + PART = ogDiskToDev (disk, par) + if PART is None: return + + sz = subprocess.run (['partx', '-gbo', 'SIZE', PART], capture_output=True, text=True).stdout.strip() + if sz: return int (int (sz) / 1024) + + sz = subprocess.run (['lvs', '--noheadings', '-o', 'lv_size', '--units', 'k', PART], capture_output=True, text=True).stdout.strip() + if sz: return int (sz) + + return FileSystemLib.ogGetFsSize (disk, par) + + +#/** +# ogGetPartitionsNumber int_ndisk +#@brief Detecta el numero de particiones del disco duro indicado. +#@param int_ndisk nº de orden del disco +#@return Devuelve el numero paritiones del disco duro indicado +#@warning Salidas de errores no determinada +#@attention Requisitos: parted +#@note Notas sin especificar +#*/ ## +def ogGetPartitionsNumber (disk): + DISK = ogDiskToDev (disk) + if not DISK: return None + out = 0 + + pttype = ogGetPartitionTableType (disk) + if pttype in ['GPT', 'MSDOS']: + partx_out = subprocess.run (['partx', '-gso', 'NR', DISK], capture_output=True, text=True).stdout + lines = partx_out.splitlines() + if len(lines): + out = lines[-1].strip() + elif 'LVM' == pttype: + lvs_out = subprocess.run (['lvs', '--noheadings', DISK], capture_output=True, text=True).stdout + lines = lvs_out.splitlines() + out = len (lines) + elif 'ZPOOL' == pttype: + if subprocess.run (['zpool', 'list']).returncode: + subprocess.run (['modprobe', 'zfs']) + subprocess.run (['zpool', 'import', '-f', '-R', '/mnt', '-N', '-a']) + blkid = subprocess.run (['blkid', '-s', 'LABEL', '-o', 'value', DISK], capture_output=True, text=True).stdout + zfs_out = subprocess.run (['zfs', 'list', '-Hp', '-o', 'name,canmount,mountpoint', '-r', blkid], capture_output=True, text=True).stdout + out = 0 + for l in zfs_out.splitlines(): + items = l.split() + if len(items) < 3: continue + if 'on' == items[1] and 'none' != items[2]: out += 1 + + return int (out) + + +#/** +# ogGetPartitionTableType int_ndisk +#@brief Devuelve el tipo de tabla de particiones del disco (GPT o MSDOS) +#@param int_ndisk nº de orden del disco +#@return str_tabletype - Tipo de tabla de paritiones +#@warning Salidas de errores no determinada +#@note tabletype = { MSDOS, GPT } +#@note Requisitos: blkid, parted, vgs +#*/ ## +def ogGetPartitionTableType (disk): + DISK = ogDiskToDev (disk) + if DISK is None: return + + m = os.stat (DISK, follow_symlinks=True).st_mode + if stat.S_ISBLK (m): + lines = subprocess.run (['parted', '--script', '--machine', DISK, 'print'], capture_output=True, text=True).stdout.splitlines() + for l in lines: + elems = l.split (':') + if DISK == elems[0]: + type = elems[5].upper() + break + + # Comprobar si es volumen lógico. + if os.path.isdir (DISK) and 0 == subprocess.run (['vgs', DISK]).returncode: + type = 'LVM' + + # Comprobar si es pool de ZFS. + if not type or 'UNKNOWN' == type: + if 'zfs' in subprocess.run (['blkid', '-s', 'TYPE', DISK], capture_output=True, text=True).stdout: + type = 'ZPOOL' + + return type + + +#/** +# ogGetPartitionType int_ndisk int_npartition +#@brief Devuelve el mnemonico con el tipo de partición. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return Mnemonico +#@note Mnemonico: valor devuelto por ogIdToType. +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#*/ ## +def ogGetPartitionType (disk, par): + ID = ogGetPartitionId (disk, par) + if ID is None: return None + + return ogIdToType (ID) + + +#/** +# ogHidePartition int_ndisk int_npartition +#@brief Oculta un apartición visible. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return (nada) +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND disco o particion no detectado (no es un dispositivo). +#@exception OG_ERR_PARTITION tipo de partición no reconocido. +#*/ ## +def ogHidePartition (disk, par): + PART = ogDiskToDev (disk, par) + if not PART: return None + + TYPE = ogGetPartitionType (disk, par) + if 'NTFS' == TYPE: NEWTYPE = 'HNTFS' + elif 'FAT32' == TYPE: NEWTYPE = 'HFAT32' + elif 'FAT16' == TYPE: NEWTYPE = 'HFAT16' + elif 'FAT12' == TYPE: NEWTYPE = 'HFAT12' + elif 'WINDOWS' == TYPE: NEWTYPE = 'WIN-RESERV' + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, TYPE) + return None + + ogSetPartitionType (disk, par, NEWTYPE) + + +#/** +# ogIdToType int_idpart +#@brief Devuelve el identificador correspondiente a un tipo de partición. +#@param int_idpart identificador de tipo de partición. +#@return str_parttype mnemónico de tipo de partición. +#@exception OG_ERR_FORMAT Formato incorrecto. +#*/ ## +def ogIdToType (ID): + # Obtener valor hexadecimal de 4 caracteres rellenado con 0 por delante. + ID = ID.zfill(4).lower() + + id2type = { + '0000': 'EMPTY', + '0001': 'FAT12', + '0005': 'EXTENDED', + '000f': 'EXTENDED', + '0006': 'FAT16', + '000e': 'FAT16', + '0007': 'NTFS', + '000b': 'FAT32', + '000c': 'FAT32', + '0011': 'HFAT12', + '0012': 'COMPAQDIAG', + '0016': 'HFAT16', + '001e': 'HFAT16', + '0017': 'HNTFS', + '001b': 'HFAT32', + '001c': 'HFAT32', + '0042': 'WIN-DYNAMIC', + '0082': 'LINUX-SWAP', + '8200': 'LINUX-SWAP', + '0083': 'LINUX', + '8300': 'LINUX', + '008e': 'LINUX-LVM', + '8E00': 'LINUX-LVM', + '00a5': 'FREEBSD', + 'a503': 'FREEBSD', + '00a6': 'OPENBSD', + '00a7': 'CACHE', # (compatibilidad con Brutalix) + '00af': 'HFS', + 'af00': 'HFS', + '00be': 'SOLARIS-BOOT', + 'be00': 'SOLARIS-BOOT', + '00bf': 'SOLARIS', + 'bf00145': 'SOLARIS', + '00ca': 'CACHE', + 'ca00': 'CACHE', + '00da': 'DATA', + '00ee': 'GPT', + '00ef': 'EFI', + 'ef00': 'EFI', + '00fb': 'VMFS', + '00fd': 'LINUX-RAID', + 'fd00': 'LINUX-RAID', + '0700': 'WINDOWS', + '0c01': 'WIN-RESERV', + '7f00': 'CHROMEOS-KRN', + '7f01': 'CHROMEOS', + '7f02': 'CHROMEOS-RESERV', + '8301': 'LINUX-RESERV', + 'a500': 'FREEBSD-DISK', + 'a501': 'FREEBSD-BOOT', + 'a502': 'FREEBSD-SWAP', + 'ab00': 'HFS-BOOT', + 'af01': 'HFS-RAID', + 'bf02': 'SOLARIS-SWAP', + 'bf03': 'SOLARIS-DISK', + 'ef01': 'MBR', + 'ef02': 'BIOS-BOOT', + '10000': 'LVM-LV', + '10010': 'ZFS-VOL', + } + if ID in id2type: + return id2type[ID] + return 'UNKNOWN' + + +# ogIsDiskLocked int_ndisk +#@brief Comprueba si un disco está bloqueado por una operación de uso exclusivo. +#@param int_ndisk nº de orden del disco +#@return Código de salida: 0 - bloqueado, 1 - sin bloquear o error. +#@note Los ficheros de bloqueo se localizan en \c /var/lock/dev, siendo \c dev el dispositivo de la partición o de su disco, sustituyendo el carácter "/" por "-". +#*/ ## +def ogIsDiskLocked (disk): + DISK = ogDiskToDev (disk) + if not DISK: return False + return os.path.isfile (f'/var/lock/lock{DISK.replace("/", "-")}') + + +#/** +# ogListPartitions int_ndisk +#@brief Lista las particiones definidas en un disco. +#@param int_ndisk nº de orden del disco +#@return str_parttype:int_partsize ... +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND disco o particion no detectado (no es un dispositivo). +#@note Requisitos: \c parted \c awk +#@attention El nº de partición se indica por el orden de los párametros \c parttype:partsize +#@attention Las tuplas de valores están separadas por espacios. +#*/ ## +def ogListPartitions (disk): + DISK = ogDiskToDev (disk) + if not DISK: return None + + p = [] + NPARTS = ogGetPartitionsNumber (disk) + for PART in range (1, NPARTS + 1): + t = ogGetPartitionType (disk, PART) + TYPE = ogGetPartitionType (disk, PART) or 'EMPTY' + SIZE = ogGetPartitionSize (disk, PART) or 0 + p.append (f'{TYPE}:{SIZE}') + + return p + + +#/** +# ogListPrimaryPartitions int_ndisk +#@brief Metafunción que lista las particiones primarias no vacías de un disco. +#@param int_ndisk nº de orden del disco +#@see ogListPartitions +#*/ ## +def ogListPrimaryPartitions (disk): + PTTYPE = ogGetPartitionTableType (disk) + if not PTTYPE: return None + + PARTS = ogListPartitions (disk) + if not PARTS: return None + + if 'GPT' == PTTYPE: + res = [] + for idx in range (len(PARTS),0,-1): + item = PARTS[idx-1] + if 0==len(res) and 'EMPTY:0' == item: continue + res.insert (0, item) + return res + elif 'MSDOS' == PTTYPE: + return PARTS[0:4] + + +#/** +# ogListLogicalPartitions int_ndisk +#@brief Metafunción que lista las particiones lógicas de una tabla tipo MSDOS. +#@param int_ndisk nº de orden del disco +#@see ogListPartitions +#*/ ## +def ogListLogicalPartitions (disk): + PTTYPE = ogGetPartitionTableType (disk) + if not PTTYPE: return None + + PARTS = ogListPartitions (disk) + if not PARTS: return None + + return PARTS[4:] + + +#/** +# ogLockDisk int_ndisk +#@brief Genera un fichero de bloqueo para un disco en uso exlusivo. +#@param int_ndisk nº de orden del disco +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@note El fichero de bloqueo se localiza en \c /var/lock/disk, siendo \c disk el dispositivo del disco, sustituyendo el carácter "/" por "-". +#*/ ## +def ogLockDisk (disk): + DISK = ogDiskToDev (disk) + if not DISK: return None + open (f'/var/lock/lock{DISK.replace("/", "-")}', 'a').close() + + +#/** +# ogSetPartitionActive int_ndisk int_npartition +#@brief Establece cual es la partición activa de un disco. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return (nada). +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositivo. +#@note Requisitos: parted +#*/ ## +def ogSetPartitionActive (disk, par): + if InventoryLib.ogIsEfiActive(): + SystemLib.ogEcho (['session', 'log'], 'warning', f'EFI: {ogGlobals.lang.MSG_DONTUSE} ogSetPartitionActive') + return + + DISK = ogDiskToDev (disk) + if DISK is None: return + + PART = ogDiskToDev (disk, par) + if PART is None: return + + subprocess.run (["parted", "-s", DISK, "set", par, "boot", "on"]) + return + + +#/** +# ogSetPartitionId int_ndisk int_npartition hex_partid +#@brief Cambia el identificador de la partición. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@param hex_partid identificador de tipo de partición +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositivo. +#@exception OG_ERR_OUTOFLIMIT Valor no válido. +#@exception OG_ERR_PARTITION Error al cambiar el id. de partición. +#@attention Requisitos: fdisk, sgdisk +#*/ ## +## for GPT partitions, id must be one of the valid types as reported by 'sgdisk --list-types', eg. 0700 or 8200 +def ogSetPartitionId (disk, par, id): + DISK = ogDiskToDev (disk) + if not DISK: return None + + PART = ogDiskToDev (disk, par) + if not PART: return None + +# Error si el id. de partición no es hexadecimal. + if not re.match ('^[0-9A-Fa-f]+$', id): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_OUTOFLIMIT, id) + return None + +# Elección del tipo de partición. + PTTYPE = ogGetPartitionTableType (disk) + if 'GPT' == PTTYPE: + p = subprocess.run (['sgdisk', f'-t{par}:{id.upper()}', DISK]) + elif 'MSDOS' == PTTYPE: + p = subprocess.run (['sfdisk', '--id', DISK, par, id.upper()]) + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_OUTOFLIMIT, f'{disk},{PTTYPE}') + return None + +# MSDOS) Correcto si fdisk sin error o con error pero realiza Syncing + if 0 == p.returncode: + subprocess.run (['partprobe', DISK]) + return True + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk},{part},{id}') + return None + + +#/** +# ogSetPartitionSize int_ndisk int_npartition int_size +#@brief Muestra el tamano en KB de una particion determinada. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@param int_size tamaño de la partición (en KB) +#@return (nada) +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND disco o particion no detectado (no es un dispositivo). +#@note Requisitos: sfdisk, awk +#@todo Compruebar que el tamaño sea numérico positivo y evitar que pueda solaparse con la siguiente partición. +#*/ ## +def ogSetPartitionSize (disk, par, size): + DISK = ogDiskToDev (disk) + if not DISK: return None + + PART = ogDiskToDev (disk, par) + if not PART: return None + +# Convertir tamaño en KB a sectores de 512 B. + SIZE = 2 * int (size) +# Redefinir el tamaño de la partición. + p = subprocess.run (['sfdisk', '-f', '-uS', f'-N{par}', DISK], input=f',{SIZE}', text=True) + if p.returncode: + ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk},{par}') + return None + subprocess.run (['partprobe', DISK]) + + +#/** +# ogSetPartitionType int_ndisk int_npartition str_type +#@brief Cambia el identificador de la partición. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@param str_type mnemónico de tipo de partición +#@return (nada) +#@attention Requisitos: fdisk, sgdisk +#*/ ## +def ogSetPartitionType (disk, par, t): + DISK = ogDiskToDev (disk) + if not DISK: return None + + PART = ogDiskToDev (disk, par) + if not PART: return None + + PTTYPE = ogGetPartitionTableType (disk) + if not PTTYPE: return None + + ID = ogTypeToId (t, PTTYPE) + if not ID: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{t},{PTTYPE}') + return None + + ogSetPartitionId (disk, par, ID) + + +#/** +# ogTypeToId str_parttype [str_tabletype] +#@brief Devuelve el identificador correspondiente a un tipo de partición. +#@param str_parttype mnemónico de tipo de partición. +#@param str_tabletype mnemónico de tipo de tabla de particiones (MSDOS por defecto). +#@return int_idpart identificador de tipo de partición. +#@exception OG_ERR_FORMAT Formato incorrecto. +#@note tabletype = { MSDOS, GPT }, (MSDOS, por defecto) +#*/ ## +#ogTypeToId ('LINUX') => "83" +#ogTypeToId ('LINUX', 'MSDOS') => "83" +def ogTypeToId (type, pttype='MSDOS'): + data = { + 'GPT': { + 'EMPTY': '0', + 'WINDOWS': '0700', + 'NTFS': '0700', + 'EXFAT': '0700', + 'FAT32': '0700', + 'FAT16': '0700', + 'FAT12': '0700', + 'HNTFS': '0700', + 'HFAT32': '0700', + 'HFAT16': '0700', + 'HFAT12': '0700', + 'WIN-RESERV': '0C01', + 'CHROMEOS-KRN': '7F00', + 'CHROMEOS': '7F01', + 'CHROMEOS-RESERV': '7F02', + 'LINUX-SWAP': '8200', + 'LINUX': '8300', + 'EXT2': '8300', + 'EXT3': '8300', + 'EXT4': '8300', + 'REISERFS': '8300', + 'REISER4': '8300', + 'XFS': '8300', + 'JFS': '8300', + 'LINUX-RESERV': '8301', + 'LINUX-LVM': '8E00', + 'FREEBSD-DISK': 'A500', + 'FREEBSD-BOOT': 'A501', + 'FREEBSD-SWAP': 'A502', + 'FREEBSD': 'A503', + 'HFS-BOOT': 'AB00', + 'HFS': 'AF00', + 'HFS+': 'AF00', + 'HFSPLUS': 'AF00', + 'HFS-RAID': 'AF01', + 'SOLARIS-BOOT': 'BE00', + 'SOLARIS': 'BF00', + 'SOLARIS-SWAP': 'BF02', + 'SOLARIS-DISK': 'BF03', + 'CACHE': 'CA00', + 'EFI': 'EF00', + 'LINUX-RAID': 'FD00', + }, + 'MSDOS': { + 'EMPTY': '0', + 'FAT12': '1', + 'EXTENDED': '5', + 'FAT16': '6', + 'WINDOWS': '7', + 'NTFS': '7', + 'EXFAT': '7', + 'FAT32': 'b', + 'HFAT12': '11', + 'HFAT16': '16', + 'HNTFS': '17', + 'HFAT32': '1b', + 'LINUX-SWAP': '82', + 'LINUX': '83', + 'EXT2': '83', + 'EXT3': '83', + 'EXT4': '83', + 'REISERFS': '83', + 'REISER4': '83', + 'XFS': '83', + 'JFS': '83', + 'LINUX-LVM': '8e', + 'FREEBSD': 'a5', + 'OPENBSD': 'a6', + 'HFS': 'af', + 'HFS+': 'af', + 'SOLARIS-BOOT': 'be', + 'SOLARIS': 'bf', + 'CACHE': 'ca', + 'DATA': 'da', + 'GPT': 'ee', + 'EFI': 'ef', + 'VMFS': 'fb', + 'LINUX-RAID': 'fd', + }, + 'LVM': { + 'LVM-LV': '10000', + }, + 'ZVOL': { + 'ZFS-VOL': '10010', + }, + } + + if pttype.upper() not in data: return None + if type.upper() not in data[pttype.upper()]: return None + return data[pttype.upper()][type.upper()] + + +#/** +# ogUnhidePartition int_ndisk int_npartition +#@brief Hace visible una partición oculta. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return (nada) +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND disco o particion no detectado (no es un dispositivo). +#@exception OG_ERR_PARTITION tipo de partición no reconocido. +#*/ ## +def ogUnhidePartition (disk, par): + PART = ogDiskToDev (disk, par) + if not PART: return None + + TYPE = ogGetPartitionType (disk, par) + if 'HNTFS' == TYPE: NEWTYPE = 'NTFS' + elif 'HFAT32' == TYPE: NEWTYPE = 'FAT32' + elif 'HFAT16' == TYPE: NEWTYPE = 'FAT16' + elif 'HFAT12' == TYPE: NEWTYPE = 'FAT12' + elif 'WIN-RESERV' == TYPE: NEWTYPE = 'WINDOWS' + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, TYPE) + return None + + ogSetPartitionType (disk, par, NEWTYPE) + + +#/** +# ogUnlockDisk int_ndisk +#@brief Elimina el fichero de bloqueo para un disco. +#@param int_ndisk nº de orden del disco +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@note El fichero de bloqueo se localiza en \c /var/lock/disk, siendo \c disk el dispositivo del disco, sustituyendo el carácter "/" por "-". +#*/ ## +def ogUnlockDisk (disk): + DISK = ogDiskToDev (disk) + if not DISK: return None + os.remove (f'/var/lock/lock{DISK.replace("/", "-")}') + + +#/** +# ogUpdatePartitionTable +#@brief Fuerza al kernel releer la tabla de particiones de los discos duros +#@param no requiere +#@return informacion propia de la herramienta +#@note Requisitos: \c partprobe +#@warning pendiente estructurar la funcion a opengnsys +#*/ ## +def ogUpdatePartitionTable(): + for disk in ogDiskToDev(): + subprocess.run(["partprobe", disk]) diff --git a/client/lib/python3/FileLib.py b/client/lib/python3/FileLib.py new file mode 100644 index 0000000..2a4adf4 --- /dev/null +++ b/client/lib/python3/FileLib.py @@ -0,0 +1,517 @@ +#/** +#@file FileLib.py +#@brief Librería o clase File +#@class File +#@brief Funciones para gestión de archivos y directorios. +#@warning License: GNU GPLv3+ +#*/ + +import subprocess +import os +import shutil +import hashlib + +import ogGlobals +import SystemLib +import CacheLib +import FileSystemLib + +#/** +# ogCalculateChecksum [ str_repo | int_ndisk int_npart ] path_filepath +#@brief Devuelve la suma de comprobación (checksum) de un fichero. +#@param path_filepath camino del fichero (independiente de mayúsculas) +#@param str_repo repositorio de ficheros +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return hex_checksum Checksum del fichero +#*/ ## +#ogCalculateChecksum ([ str_repo | int_ndisk int_npartition ] path_filepath") +#ogCalculateChecksum (container='REPO', file='ubuntu.img') ==> ef899299caf8b517ce36f1157a93d8bf +#ogCalculateChecksum (disk=1, par=1, file='ubuntu.img') ==> ef899299caf8b517ce36f1157a93d8bf +def ogCalculateChecksum (disk=None, par=None, container=None, file=None): + if file is None: + raise TypeError ('missing required argument: "file"') + + if container is not None: + if disk is None and par is None: + ## we were given container= + f = ogGetPath (src=container, file=file) + dev_err = f'{container} {file}' + print (f'ogGetPath (src=({container}), file=({file})) = f ({f})') + else: + raise TypeError ('argument "container" can be specified along neither "disk" nor "par"') + + else: + if disk is not None and par is not None: + ## we were given disk= par= + f = ogGetPath (src=f'{disk} {par}', file=file) + dev_err = f'{disk} {par} {file}' + print (f'ogGetPath (src=({disk} {par}), file=({file})) = f ({f})') + elif disk is None and par is None: + ## we were given nothing + f = ogGetPath (file=file) + dev_err = file + print (f'ogGetPath (file=({file})) = f ({f})') + else: + raise TypeError ('if one of "disk" and "par" are specified, then both must be') + + if not f: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, dev_err) + return + + last_n_bytes = 1024*1024 + if last_n_bytes >= os.stat (f).st_size: + return ogCalculateFullChecksum (disk, par, container, file) + with open (f, 'rb') as fd: + fd.seek (-last_n_bytes, os.SEEK_END) + data = fd.read() + md5 = hashlib.md5(data).hexdigest() + + return md5 + + +#/** +# ogCompareChecksumFiles [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target +#@brief Metafunción que compara las sumas de comprobación almacenadas de 2 ficheros. +#@return bool_compare Valor de comparación. +#@warning No es necesario especificar la extensión ".sum". +#*/ ## +def ogCompareChecksumFiles(*args): + # Variables locales. + ARGS = args + if "help" in args: + SystemLib.ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath", "if $FUNCNAME REPO ubuntu.img CACHE ubuntu.img; then ...; fi") + return + + ARGS = args + if args[0].startswith("/"): + # Camino completo. */ (Comentario Doxygen) + SOURCE = ogGetPath(*args[:1]) + args = args[1:] + elif args[0].isdigit(): + # ndisco npartición. + SOURCE = ogGetPath(*args[:3]) + args = args[3:] + else: + # Otros: repo, cache, cdrom (no se permiten caminos relativos). + SOURCE = ogGetPath(*args[:2]) + args = args[2:] + + TARGET = ogGetPath(*args) + + try: + with open(f"{SOURCE}.sum", "r") as source_file: + source_checksum = source_file.read().strip() + with open(f"{TARGET}.sum", "r") as target_file: + target_checksum = target_file.read().strip() + + return source_checksum == target_checksum + except FileNotFoundError: + return False + + +#/** +# ogCalculateFullChecksum [ str_repo | int_ndisk int_npart ] path_filepath +#@brief Devuelve la suma COMPLETA de comprobación (checksum) de un fichero. +#@param path_filepath camino del fichero (independiente de mayúsculas) +#@param str_repo repositorio de ficheros +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return hex_checksum Checksum del fichero +#*/ ## +def ogCalculateFullChecksum (disk=None, par=None, container=None, file=None): + if file is None: + raise TypeError ('missing required argument: "file"') + + if container is not None: + if disk is None and par is None: + ## we were given container= + f = ogGetPath (src=container, file=file) + dev_err = f'{container} {file}' + print (f'ogGetPath (src=({container}), file=({file})) = f ({f})') + else: + raise TypeError ('argument "container" can be specified along neither "disk" nor "par"') + + else: + if disk is not None and par is not None: + ## we were given disk= par= + f = ogGetPath (src=f'{disk} {par}', file=file) + dev_err = f'{disk} {par} {file}' + print (f'ogGetPath (src=({disk} {par}), file=({file})) = f ({f})') + elif disk is None and par is None: + ## we were given nothing + f = ogGetPath (file=file) + dev_err = file + print (f'ogGetPath (file=({file})) = f ({f})') + else: + raise TypeError ('if one of "disk" and "par" are specified, then both must be') + + if not f: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, dev_err) + return + + md5 = hashlib.md5() + with open (f, 'rb') as fd: + for chunk in iter (lambda: fd.read (64*1024), b''): + md5.update (chunk) + return md5.hexdigest() + + + + +#/** +# ogCopyFile [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target +#@brief Metafunción para copiar un fichero de sistema OpenGnSys a un directorio. +#@see ogGetPath +#@return Progreso de la copia. +#@warning Deben existir tanto el fichero origen como el directorio destino. +#*/ ## +#ogCopyFile (src, dst) +#ogCopyFile ({container='REPO', file='newfile.txt'}, {disk=1, par=2, file='/tmp/newfile.txt'}) +#ogCopyFile ({disk=1, par=2, file='/tmp/newfile.txt'}, {container='REPO', file='newfile.txt'}) +def ogCopyFile (src, dst): + for elem in src, dst: + if elem == src: which = 'source' + else: which = 'target' + + if 'file' not in elem: + raise TypeError ('missing required argument in {which} dict:: "file"') + + if 'container' in elem: + if 'disk' not in elem and 'par' not in elem: + ## we were given container= + path = ogGetPath (src=elem['container'], file=elem['file']) + dev_err = f'{elem["container"]} {elem["file"]}' + print (f'ogGetPath {which} (src=({elem["container"]}), file=({elem["file"]})) = path ({path})') + else: + raise TypeError ('argument "container" can be specified along neither "disk" nor "par"') + + else: + if 'disk' in elem and 'par' in elem: + ## we were given disk= par= + path = ogGetPath (src=f'{elem["disk"]} {elem["par"]}', file=elem['file']) + dev_err = f'{elem["disk"]} {elem["par"]} {elem["file"]}' + print (f'ogGetPath {which} (src=({elem["disk"]} {elem["par"]}), file=({elem["file"]})) = path ({path})') + elif 'disk' not in elem and 'par' not in elem: + ## we were given nothing + path = ogGetPath (file=elem['file']) + dev_err = elem['file'] + print (f'ogGetPath {which} (file=({elem["file"]})) = path ({path})') + else: + raise TypeError ('if one of "disk" and "par" are specified, then both must be') + + if elem == src: + SOURCE = path + src_dev_err = dev_err + else: + TARGET = path + dst_dev_err = dev_err + + if not SOURCE: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {src_dev_err} not found') + return + if not TARGET: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dst_dev_err} not found') + return + print (f'nati: ogCopyFile: SOURCE ({SOURCE}) TARGET ({TARGET})') + + # Copiar fichero (para evitar problemas de comunicaciones las copias se hacen con rsync en vez de cp). + print (f'nati: ogCopyFile: rsync --progress --inplace -avh ({SOURCE}) ({TARGET})') + result = subprocess.run(["rsync", "--progress", "--inplace", "-avh", SOURCE, TARGET], capture_output=True, text=True) + return result.returncode + + +#/** +# ogDeleteFile [ str_repo | int_ndisk int_npartition ] path_filepath +#@brief Metafunción que borra un fichero de un dispositivo. +#@see ogGetPath +#@version 0.9 - Pruebas con OpenGnSys. +#@author Ramon Gomez, ETSII Universidad de Sevilla +#@date 2009-09-29 +#*/ ## +#ogDeleteFile ([ str_repo | int_ndisk int_npartition ] path_file) +#ogDeleteFile (container='REPO', file='/tmp/newfile.txt') +#ogDeleteFile (disk=1, par=2, file='/tmp/newfile.txt') +def ogDeleteFile (disk=None, par=None, container=None, file=None): + if file is None: + raise TypeError ('missing required argument: "file"') + + if container is not None: + if disk is None and par is None: + ## we were given container= + src = container + else: + raise TypeError ('argument "container" can be specified along neither "disk" nor "par"') + else: + if disk is not None and par is not None: + ## we were given disk= par= + src = f'{disk} {par}' + else: + ## we were given nothing + raise TypeError ('either "container" or both "disk" and "par" must be specified') + + f = ogGetPath (src=src, file=file) + if not f: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{src} {file}') + return + + try: + os.remove (f) + except OSError as e: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, str (e)) + return + + +#/** +# ogDeleteTree [ str_repo | int_ndisk int_npartition ] path_dirpath +#@brief Metafunción que borra todo un subárbol de directorios de un dispositivo. +#@see ogGetPath +#*/ ## +#ogDeleteTree (container='REPO', file='/tmp/newdir') +#ogDeleteTree (disk=1, par=2, file='/tmp/newdir') +def ogDeleteTree (disk=None, par=None, container=None, file=None): + if file is None: + raise TypeError ('missing required argument: "file"') + + if container is not None: + if disk is None and par is None: + ## we were given container= + src = container + else: + raise TypeError ('argument "container" can be specified along neither "disk" nor "par"') + else: + if disk is not None and par is not None: + ## we were given disk= par= + src = f'{disk} {par}' + else: + ## we were given nothing + raise TypeError ('either "container" or both "disk" and "par" must be specified') + + f = ogGetPath (src=src, file=file) + if not f: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{src} {file}') + return + + try: + shutil.rmtree (f) + except OSError as e: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, e) + return + + +#/** +# ogGetPath [ str_repo | int_ndisk int_npartition ] path_filepath +#@brief Inicia el proceso de arranque de un sistema de archivos. +#@param path_filepath camino del fichero (independiente de mayúsculas) +#@param str_repo repositorio de ficheros +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return path_file - camino completo real del fichero. +#@note repo = { REPO, CACHE, CDROM } +#@note Requisitos: \c grep \c sed +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero o dispositivo no encontrado. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#@warning En caso de error, sólo devuelve el código y no da mensajes. +#@todo Terminar de definir parámetros para acceso a repositorios. +#*/ ## +#ogGetPath (file='/mnt/sda1/windows/system32') ==> '/mnt/sda1/WINDOWS/System32' +#ogGetPath (src='REPO', file='/etc/fstab') ==> '/opt/opengnsys/images/etc/fstab' +#ogGetPath (src='1 1', file='/windows/system32') ==> '/mnt/sda1/WINDOWS/System32' +def ogGetPath (src=None, file=None): + if file is None: + raise TypeError ('missing required argument: "file"') + + f = file + if src is not None: + if 'REPO' == src: + f = os.path.join (ogGlobals.OGIMG, file.strip('/')) + elif 'CACHE' == src: + mntdir = CacheLib.ogMountCache() + if not mntdir: return None + f = os.path.join (mntdir, ogGlobals.OGIMG.strip('/'), file.strip('/')) + elif 'CDROM' == src: + mntdir = FileSystemLib.ogMountCdrom() + if not mntdir: return None + f = os.path.join (mntdir, file.strip('/')) + else: + try: + disk, part = src.split() + except ValueError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '') + return + mntdir = FileSystemLib.ogMount (disk, part) + if not mntdir: return None + f = os.path.join (mntdir, file.strip('/')) + + f = os.path.normpath (f) + + if os.path.exists (f): + filepath = f + #print (f'f ({f}) existe, filepath=f ({filepath})') + else: + # Buscar el nombre correcto en cada subdirectorio del camino. + prevfile = '' + filepath = '/' + #print (f'f ({f}) prevfile ({prevfile})') + while f != prevfile: + #print ('\nno son iguales, nueva iteracion...') + f_first_component = f.split ('/')[0] ## take 1st component + ls_path = os.path.join (filepath, f_first_component) ## "ls" makes reference to the original bash version + #print (f'f_first_component ({f_first_component}) ls_path ({ls_path})') + + ## build filepath to return + if os.path.exists (ls_path): + filepath = ls_path + #print (f'ls_path existe, filepath ({filepath})') + else: + filepath = subprocess.run (['find', filepath, '-maxdepth', '1', '-iname', f_first_component, '-print'], capture_output=True, text=True).stdout.strip() + #print (f'ls_path no existe, filepath ({filepath})') + + prevfile = f + if '/' in f: + f = '/'.join (f.split('/')[1:]) ## remove 1st component + #print (f'f ({f}) prevfile ({prevfile})') + + return filepath + + +#/** +# ogGetParentPath [ str_repo | int_ndisk int_npartition ] path_filepath +#@brief Metafunción que devuelve el camino del directorio padre. +#@see ogGetPath +#*/ ## + +#ogGetParentPath ([ str_repo | int_ndisk int_npartition ] path_filepath +#ogGetParentPath ( file='/mnt/sda1/windows/system32') ==> '/mnt/sda1/WINDOWS' +#ogGetParentPath (src='REPO', file='/etc/fstab') ==> '/opt/opengnsys/images/etc' +#ogGetParentPath (src='1 1', file='/windows/system32') ==> '/mnt/sda1/WINDOWS' +def ogGetParentPath (src=None, file=None): + if file is None: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '') + return + + if src is None: + return ogGetPath (file=os.path.dirname (file)) + else: + return ogGetPath (src=src, file=os.path.dirname('/'+file)) + +#/** +# ogIsNewerFile [ str_repo | int_ndisk int_npart ] path_source [ str_repo | int_ndisk int_npart ] path_target +#@brief Metafunción que indica se un fichero es más nuevo que otro. +#@see ogGetPath +#@return Código de salida: 0 - nuevo, 1 - antiguo o error +#@warning Deben existir tanto el fichero origen como el destino. +#*/ ## +def ogIsNewerFile(*args): + # Variables locales. + ARGS = args + if "help" in args: + SystemLib.ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_source [ str_repo | int_ndisk int_npartition ] path_target", "if $FUNCNAME REPO ubuntu.img CACHE ubuntu.img; then ... fi") + return + + ARGS = args + if args[0].startswith("/"): + # Camino completo. */ (Comentrio Doxygen) + SOURCE = ogGetPath(*args[:1]) + args = args[1:] + elif args[0].isdigit(): + # ndisco npartición. + SOURCE = ogGetPath(*args[:3]) + args = args[3:] + else: + # Otros: repo, cache, cdrom (no se permiten caminos relativos). + SOURCE = ogGetPath(*args[:2]) + args = args[2:] + + TARGET = ogGetPath(*args) + + # Comprobar que existen los ficheros origen y destino. + if not SOURCE: + SystemLib.ogRaiseError( + "session", + ogGlobals.OG_ERR_NOTFOUND, + f"Not found: {args[:-1]}" + ) + return + if not TARGET: + SystemLib.ogRaiseError( + "session", + ogGlobals.OG_ERR_NOTFOUND, + f"Not found: {args[-1]}" + ) + return + + # Devolver si el primer fichero se ha modificado después que el segundo. + return os.path.getmtime(SOURCE) > os.path.getmtime(TARGET) + +#/** +# ogMakeChecksumFile [ str_repo | int_ndisk int_npart ] path_filepath +#@brief Metafunción que guarda el valor de comprobación de un fichero. +#@see ogCalculateChecksum +#@warning Genera un fichero con extensión ".sum". +#*/ ## +def ogMakeChecksumFile(*args): + # Variables locales. + FILE = None + if "help" in args: + SystemLib.ogHelp("$FUNCNAME", "$FUNCNAME [ str_repo | int_ndisk int_npartition ] path_filepath", "$FUNCNAME REPO ubuntu.img") + return + + # Comprobar que existe el fichero y guardar su checksum. + FILE = ogGetPath(*args) + if not FILE: + SystemLib.ogRaiseError( + "session", + ogGlobals.OG_ERR_NOTFOUND, + f"Not found: {args}" + ) + return + checksum = ogCalculateChecksum(FILE) + with open(f"{FILE}.sum", "w") as f: + f.write(checksum) + + +#/** +# ogMakeDir [ str_repo | int_ndisk int_npartition ] path_dirpath +#@brief Metafunción que crea un subdirectorio vacío en un dispositivo. +#@see ogGetParentPath +#*/ ## +#ogMakeDir (container='REPO', file='/tmp/newdir') +#ogMakeDir (disk='1', par='2', file='/tmp/newdir') +def ogMakeDir (container=None, disk=None, par=None, file=None): + if file is None: + raise TypeError ('missing required argument: "file"') + + if container is not None: + if disk is None and par is None: + ## we were given container= + parent = ogGetParentPath (src=container, file=file) + dev_err = f'{container} {file}' + print (f'ogGetParentPath (src=({container}), file=({file})) = parent ({parent})') + else: + raise TypeError ('argument "container" can be specified along neither "disk" nor "par"') + + else: + if disk is not None and par is not None: + ## we were given disk= par= + parent = ogGetParentPath (src=f'{disk} {par}', file=file) + dev_err = f'{disk} {par} {file}' + print (f'ogGetParentPath (src=({disk} {par}), file=({file})) = parent ({parent})') + elif disk is None and par is None: + ## we were given nothing + parent = ogGetParentPath (file=file) + dev_err = file + print (f'ogGetParentPath (file=({file})) = parent ({parent})') + else: + raise TypeError ('if one of "disk" and "par" are specified, then both must be') + + print (f'nati: ogMakeDir: parent ({parent})') + if not parent: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found') + return None + + dst = os.path.basename (file) + print (f'nati: ogMakeDir: dst ({dst})') + os.makedirs (os.path.join (parent, dst), exist_ok=True) + return True diff --git a/client/lib/python3/FileSystemLib.py b/client/lib/python3/FileSystemLib.py new file mode 100644 index 0000000..15139f3 --- /dev/null +++ b/client/lib/python3/FileSystemLib.py @@ -0,0 +1,906 @@ +#/** +#@file FileSystemLib.py +#@brief Librería o clase FileSystem +#@class FileSystem +#@brief Funciones para gestión de sistemas de archivos. +#@warning License: GNU GPLv3+ +#*/ + +import subprocess +import sys +import os.path + +import ogGlobals +import SystemLib +import DiskLib +import CacheLib +import FileSystemLib + + +#/** +# ogCheckFs int_ndisk int_nfilesys +#@brief Comprueba el estado de un sistema de archivos. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Partición desconocida o no accesible. +#@note Requisitos: *fsck* +#@warning No se comprueban sistemas de archivos montados o bloqueados. +#@todo Definir salidas. +#*/ ## +def ogCheckFs (disk, par): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return + + data = { + 'EXT2': { 'prog': 'e2fsck', 'params': '-y', 'codes': (1, 2), }, + 'EXT3': { 'prog': 'e2fsck', 'params': '-y', 'codes': (1, 2), }, + 'EXT4': { 'prog': 'e2fsck', 'params': '-y', 'codes': (1, 2), }, + 'CACHE': { 'prog': 'e2fsck', 'params': '-y', 'codes': (1, 2), }, + 'BTRFS': { 'prog': 'btrfsck', 'codes': (1), }, + 'REISERFS': { 'prog': 'fsck.reiserfs', 'codes': (1, 2), 'input': 'Yes' }, + 'REISER4': { 'prog': 'fsck.reiser4', 'params': '-ay', }, + 'JFS': { 'prog': 'fsck.jfs', 'codes': (1, 2), }, + 'XFS': { 'prog': 'xfs_repair', }, + 'F2FS': { 'prog': 'fsck.f2fs', }, + 'NTFS': { 'prog': 'ntfsfix', }, + 'EXFAT': { 'prog': 'fsck.exfat', }, + 'FAT32': { 'prog': 'dosfsck', 'params': '-a', 'codes': (1), }, + 'FAT16': { 'prog': 'dosfsck', 'params': '-a', 'codes': (1), }, + 'FAT12': { 'prog': 'dosfsck', 'params': '-a', 'codes': (1), }, + 'HFS': { 'prog': 'fsck.hfs', 'params': '-f', }, + 'HFSPLUS': { 'prog': 'fsck.hfs', 'params': '-f', }, + 'UFS': { 'prog': 'fsck.ufs', }, + 'ZFS': { 'prog': 'fsck.zfs', }, + } + type = ogGetFsType (disk, par) + if type in data: + prog = data[type]['prog'] + params = data[type]['params'] if 'params' in data[type] else '' + codes = data[type]['codes'] if 'codes' in data[type] else [] + input = data[type]['input'] if 'input' in data[type] else None + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk}, {par}, {type}') + return None + + ogUnmount (disk, par) + if ogIsMounted (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}') + return None + if ogIsLocked (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{disk} {par}') + return None + + ogLock (disk, par) + rc = subprocess.run ([prog] + params.split() + [PART], input=input, text=True).returncode + if 0 == rc or rc in codes: + errcode = 0 + elif 127 == rc: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, prog) + errcode = ogGlobals.OG_ERR_NOTEXEC + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}') + errcode = ogGlobals.OG_ERR_PARTITION + + ogUnlock (disk, par) + return not errcode ## reverse to indicate success + + +#/** +# ogExtendFs int_ndisk int_nfilesys +#@brief Extiende un sistema de archivos al tamaño de su partición. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Partición desconocida o no accesible. +#@note Requisitos: *resize* +#*/ ## +def ogExtendFs (disk, par): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return + + data = { + 'EXT2': { 'prog': 'resize2fs', 'params': '-f', }, + 'EXT3': { 'prog': 'resize2fs', 'params': '-f', }, + 'EXT4': { 'prog': 'resize2fs', 'params': '-f', }, + 'BTRFS': { 'prog': 'btrfs', 'params': 'filesystem resize max', 'domount': True }, + 'REISERFS': { 'prog': 'resize_reiserfs', 'params': '-f', }, + 'REISER4': { 'prog': 'resize_reiserfs', 'params': '-f', }, + 'NTFS': { 'prog': 'ntfsresize', 'params': '-f', 'input': 'y' }, + 'F2FS': { 'unsupported': True }, + 'JFS': { 'unsupported': True }, + 'NILFS2': { 'unsupported': True }, # try "nilfs-resize" + 'XFS': { 'unsupported': True }, + 'EXFAT': { 'unsupported': True }, + 'FAT32': { 'unsupported': True }, # try "fatresize" + 'FAT16': { 'unsupported': True }, # try "fatresize" + 'HFS': { 'unsupported': True }, + 'HFSPLUS': { 'unsupported': True }, + 'UFS': { 'unsupported': True }, + } + + type = ogGetFsType (disk, par) + if type in data: + prog = data[type]['prog'] if 'prog' in data[type] else None + params = data[type]['params'] if 'params' in data[type] else None + domount = data[type]['domount'] if 'domount' in data[type] else False + input = data[type]['input'] if 'input' in data[type] else None + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par} {type}') + return + + if not prog: return None + + if domount: + PART = ogMount (disk, par) + if not PART: return None + else: + ogUnmount (disk, par) + if ogIsMounted (disk, par): + SystemLib.ogRaiseError([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}') + return None + +# Error si el sistema de archivos está bloqueado. + if ogIsLocked (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{disk} {par}') + return None + +# Redimensionar en modo uso exclusivo. + ogLock (disk, par) + try: + if input: + rc = subprocess.run ([prog] + params.split() + [PART], input=input, text=True).returncode + else: + rc = subprocess.run ([prog] + params.split() + [PART]).returncode + except FileNotFoundError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, prog) + rc = ogGlobals.OG_ERR_NOTEXEC + except: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}') + rc = ogGlobals.OG_ERR_PARTITION + + ogUnlock (disk, par) + return not rc ## reverse to indicate success + + +#/** +# ogFormat int_ndisk int_nfilesys | CACHE +#@see ogFormatFs ogFormatCache +#*/ ## + +def ogFormat (disk, par=None, fs=None, label=None): + if disk.lower() == "cache": + return CacheLib.ogFormatCache() + else: + return ogFormatFs (disk, par, fs=fs, label=label) + + +#/** +# ogFormatFs int_ndisk int_nfilesys [type_fstype] [str_label] +#@brief Formatea un sistema de ficheros según el tipo de su partición. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@param type_fstype mnemónico de sistema de ficheros a formatear (opcional al reformatear) +#@param str_label etiqueta de volumen (opcional) +#@return (por determinar) +#@exception OG_ERR_FORMAT Formato de ejecución incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Partición no accesible o desconocida. +#@note Requisitos: mkfs* +#@warning No formatea particiones montadas ni bloqueadas. +#@todo Definir salidas. +#*/ ## +def ogFormatFs (disk, par, fs=None, label=None): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return + + if ogIsMounted (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_DONTFORMAT, f'{ogGlobals.lang.MSG_MOUNT}: {disk} {par}') + return None + if ogIsLocked (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f"{disk} {par}") + return None + + if not fs: + fs = ogGetFsType (disk, par) + + if not fs: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"{disk} {par} ...") + return None + + data = { + 'EXT2': { 'PROG': 'mkfs.ext2', 'PARAMS': '-F' }, + 'EXT3': { 'PROG': 'mkfs.ext3', 'PARAMS': '-F' }, + 'EXT4': { 'PROG': 'mkfs.ext4', 'PARAMS': '-F' }, + 'BTRFS': { 'PROG': 'mkfs.btrfs', 'PARAMS': '-f' }, + 'REISERFS': { 'PROG': 'mkfs.reiserfs', 'PARAMS': '-f', 'LABELPARAM': '-l' }, + 'REISER4': { 'PROG': 'mkfs.reiser4', 'PARAMS': '-f', 'INPUT': 'y\n' }, + 'XFS': { 'PROG': 'mkfs.xfs', 'PARAMS': '-f' }, + 'JFS': { 'PROG': 'mkfs.jfs', 'INPUT': 'y\n' }, + 'F2FS': { 'PROG': 'mkfs.f2fs', 'LABELPARAM': '-l' }, + 'NILFS2': { 'PROG': 'mkfs.nilfs2', 'PARAMS': '-f' }, + 'LINUX-SWAP': { 'PROG': 'mkswap' }, + 'NTFS': { 'PROG': 'mkntfs', 'PARAMS': '-f' }, + 'EXFAT': { 'PROG': 'mkfs.exfat', 'LABELPARAM': '-n' }, + 'FAT32': { 'PROG': 'mkdosfs', 'PARAMS': '-F 32', 'LABELPARAM': '-n' }, + 'FAT16': { 'PROG': 'mkdosfs', 'PARAMS': '-F 16', 'LABELPARAM': '-n' }, + 'FAT12': { 'PROG': 'mkdosfs', 'PARAMS': '-F 12', 'LABELPARAM': '-n' }, + 'HFS': { 'PROG': 'mkfs.hfs' }, + 'HFSPLUS': { 'PROG': 'mkfs.hfsplus', 'LABELPARAM': '-v' }, + 'UFS': { 'PROG': 'mkfs.ufs', 'PARAMS': '-O 2' }, + } + if fs not in data: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk} {par} {fs}") + return + + d = data[fs] + prog = d['PROG'] + params = d['PARAMS'] if 'PARAMS' in d else '' + labelparam = d['LABELPARAM'] if 'LABELPARAM' in d else '' + input = d['INPUT'] if 'INPUT' in d else '' + + if label == "CACHE": + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f"{ogGlobals.lang.MSG_RESERVEDVALUE}: CACHE") + return + if label: + params = f"{params} {labelparam or '-L'} {label}" + + ogLock (disk, par) + subprocess.run (['umount', PART]) + try: + if input: + errcode = subprocess.run ([prog] + params.split (' ') + [PART]).returncode + else: + errcode = subprocess.run ([prog] + params.split (' ') + [PART], input=input, text=True).returncode + except FileNotFoundError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, prog) + errcode = ogGlobals.OG_ERR_NOTEXEC + except: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk} {par}") + errcode = ogGlobals.OG_ERR_PARTITION + + ogUnlock (disk, par) + return errcode + + +#/** +# ogGetFsSize int_ndisk int_npartition [str_unit] +#@brief Muestra el tamanio del sistema de archivos indicado, permite definir la unidad de medida, por defecto GB +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@param str_unit unidad (opcional, por defecto: KB) +#@return float_size - Tamaño del sistema de archivos +#@note str_unit = { KB, MB, GB, TB } +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositivo. +#*/ ## +def ogGetFsSize (disk, par, unit='KB'): + factor = 1 + if unit.upper() == "MB": + factor = 1024 + elif unit.upper() == "GB": + factor = 1024 * 1024 + elif unit.upper() == "TB": + factor = 1024 * 1024 * 1024 + elif unit.upper() != "KB": + SystemLib.ogRaiseError ( + [], + ogGlobals.OG_ERR_FORMAT, + f"{unit} != {{ KB, MB, GB, TB }}" + ) + return + + # Obtener el tamaño del sistema de archivo (si no está formateado; tamaño = 0). + mnt = FileSystemLib.ogMount (disk, par) + if mnt: + result = subprocess.run(["df", "-BK", mnt], capture_output=True, text=True) + val = result.stdout.split("\n")[1].split()[1] + val = val.replace ('K', '') + sz = int (val) / factor + else: + sz = 0 + + return int (sz) + + +#/** +# ogGetFsType int_ndisk int_nfilesys +#@brief Devuelve el mnemonico con el tipo de sistema de archivos. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return Mnemonico +#@note Mnemonico: { EXT2, EXT3, EXT4, BTRFS, REISERFS, XFS, JFS, FAT12, FAT16, FAT32, NTFS, LINUX-SWAP, LINUX-LVM, LINUX-RAID, HFS, HFSPLUS, CACHE } +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#*/ ## +def ogGetFsType(disk, part): + PART = DiskLib.ogDiskToDev(disk, part) + if not PART: return + + TYPE = None + if PART.startswith("/"): + out = subprocess.run(["blkid", "-o", "export", PART], capture_output=True, text=True).stdout.splitlines() + for line in out: + if line.startswith("TYPE="): + TYPE = line.split("=")[1].upper() + break + else: + try: + subprocess.run(["zfs", "mount", PART]) + except FileNotFoundError: + SystemLib.ogRaiseError ( + [], + ogGlobals.OG_ERR_NOTEXEC, + 'zfs' + ) + return + out = subprocess.run(["mount"], capture_output=True, text=True).stdout.splitlines() + for line in out: + if line.startswith(PART): + TYPE = line.split()[4].upper() + break + + if not TYPE: + SystemLib.ogRaiseError ( + [], + ogGlobals.OG_ERR_NOTFOUND, + f'{disk} {part}' + ) + return + + # Componer valores correctos. + if TYPE == "EXT4": + if f"{disk} {part}" == CacheLib.ogFindCache(): + if ogIsFormated(disk, part): + TYPE = "CACHE" + elif TYPE == "VFAT": + result = subprocess.run(["blkid", "-po", "export", PART], capture_output=True, text=True) + for line in result.stdout.split("\n"): + if line.startswith("VERSION="): + TYPE = line.split("=")[1].upper() + break + elif TYPE == "SWAP": + TYPE = "LINUX-SWAP" + elif TYPE.startswith("LVM"): + TYPE = "LINUX-LVM" + elif "RAID" in TYPE: + TYPE = "LINUX-RAID" + elif TYPE == "ZFS_MEMBER": + TYPE = "ZVOL" + elif "_MEMBER" in TYPE: + TYPE = TYPE.replace("_MEMBER", "") + + return TYPE + + +#/** +# ogGetMountPoint int_ndisk int_nfilesys +#@brief Devuelve el punto de montaje de un sistema de archivos. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return Punto de montaje +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@note Requisitos: \c mount* \c awk +#*/ ## + +def ogGetMountPoint(disk, par): + PART = DiskLib.ogDiskToDev(disk, par) + if not PART: return + + return subprocess.run(["findmnt", "-n", "-o", "TARGET", PART], capture_output=True, text=True).stdout.strip() + + + +#/** +# ogIsFormated int_ndisk int_nfilesys +#@brief Comprueba si un sistema de archivos está formateado. +#@param int_ndisk nº de orden del disco o volumen. +#@param int_nfilesys nº de orden del sistema de archivos +#@return Código de salida: True - formateado, False - sin formato o error. +#*/ ## +def ogIsFormated(disk, part): + PART = DiskLib.ogDiskToDev (disk, part) + if not PART: + return + + # Revisar tipo de sistema de archivos. + if PART.startswith("/"): + out = subprocess.run(["blkid", "-s", "TYPE", PART], capture_output=True, text=True).stdout.strip() + if 'swap' in out: return False + if '_member' in out: return False + return bool(out) + else: + out = subprocess.run(["zfs", "list", "-Hp", "-o", "canmount", PART], capture_output=True, text=True).stdout.strip() + return out == "on" + + + +#/** +# ogIsLocked int_ndisk int_npartition +#@see ogIsPartitionLocked +#*/ + +def ogIsLocked(disk, par): + return ogIsPartitionLocked(disk, par) + + +#/** +# ogIsPartitionLocked int_ndisk int_npartition +#@brief Comprueba si una partición o su disco están bloqueados por una operación de uso exclusivo. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return Código de salida: 0 - bloqueado, 1 - sin bloquear o error. +#@note Los ficheros de bloqueo se localizan en \c /var/lock/dev, siendo \c dev el dispositivo de la partición o de su disco, sustituyendo el carácter "/" por "-". +#*/ ## +def ogIsPartitionLocked(disk, par): + DISK = DiskLib.ogDiskToDev(disk) + PART = DiskLib.ogDiskToDev(disk, par) + if not PART: return + + LOCKDISK = f"/var/lock/lock{DISK.replace('/', '-')}" + LOCKPART = f"/var/lock/lock{PART.replace('/', '-')}" + rc = os.path.isfile(LOCKDISK) or os.path.isfile(LOCKPART) + return rc + +#/** +# ogIsMounted int_ndisk int_nfilesys +#@brief Comprueba si un sistema de archivos está montado. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return Código de salida: 0 - montado, 1 - sin montar o error. +#*/ ## +def ogIsMounted (disk, par): + return bool (ogGetMountPoint (disk, par)) + + +#/** +# ogIsReadonly int_ndisk int_nfilesys +#@brief Comprueba si un sistema de archivos está montado solo de lectura. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return Código de salida: 0 - montado solo de lectura, 1 - con escritura o no montado. +#@version 1.1.0 - Primera versión para OpenGnsys. +#@author Ramon Gomez, ETSII Universidad de Sevilla +#@date 2016-01-20 +#*/ ## + +def ogIsReadonly(disk, par): + PART = DiskLib.ogDiskToDev(disk, par) + if not PART: return + + result = subprocess.run(["findmnt", "-n", "-o", "OPTIONS", PART], capture_output=True, text=True) + options = result.stdout.strip().split(",") + return "ro" in options + + +#/** +# ogIsWritable int_ndisk int_nfilesys +#@brief Comprueba si un sistema de archivos está montado de lectura y escritura. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return Código de salida: 0 - lectura y escritura, 1 - solo lectura o no montado. +#*/ ## +def ogIsWritable (disk, par): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return + + result = subprocess.run(["findmnt", "-n", "-o", "OPTIONS", PART], capture_output=True, text=True) + options = result.stdout.strip().split(",") + return "rw" in options + + +#/** +# ogLock int_ndisk int_npartition +#@see ogLockPartition +#*/ +def ogLock(disk, par): + return ogLockPartition(disk, par) + +#/** +# ogLockPartition int_ndisk int_npartition +#@brief Genera un fichero de bloqueo para una partición en uso exlusivo. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@note El fichero de bloqueo se localiza en \c /var/lock/part, siendo \c part el dispositivo de la partición, sustituyendo el carácter "/" por "-". +#*/ ## +def ogLockPartition (disk, par): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return + + LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}" + try: + open (LOCKFILE, 'w').close() + except: + return False + return True + + +#/** +# ogMount int_ndisk int_nfilesys +#@see ogMountFs ogMountCache ogMountCdrom +#*/ ## +def ogMount(*args): + if 1 == len (args): + if 'cache' == args[0].lower(): + return DiskLib.ogMountCache() + elif 'cdrom' == args[0].lower(): + return ogMountCdrom() + elif 2 == len (args): + return ogMountFs(args[0], args[1]) + + +#/** +# ogMountFirstFs int_ndisk +#@brief Monta el primer sistema de archivos disponible en el disco. +#@param int_ndisk nº de orden del disco +#@return Punto de montaje del primer sistema de archivos detectado +#*/ ## +def ogMountFirstFs (disk): + NPARTS = DiskLib.ogGetPartitionsNumber (disk) + for PART in range (1, NPARTS + 1): + MNTDIR = ogMount (disk, PART) + if MNTDIR: + return MNTDIR + SystemLib.ogRaiseError ('session', ogGlobals.OG_ERR_NOTFOUND, f'{disk}') + return ogGlobals.OG_ERR_NOTFOUND + +#/** +# ogMountFs int_ndisk int_nfilesys +#@brief Monta un sistema de archivos. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return Punto de montaje +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Tipo de particion desconocido o no se puede montar. +#*/ ## +def ogMountFs (disk, par): + dev = DiskLib.ogDiskToDev (disk, par) + if not dev: return + + mntdir = ogGetMountPoint (disk, par) + if mntdir: return mntdir + + if ogIsLocked (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_PARTITION}, {disk} {par}') + return + + # El camino de un dispositivo normal comienza por el carácter "/". + if dev.startswith ('/'): + # Crear punto de montaje o enlace simbólico para caché local. + mntdir = dev.replace ('/dev', '/mnt') + if f"{disk} {par}" == CacheLib.ogFindCache(): + os.makedirs(ogGlobals.OGCAC, exist_ok=True) + try: + os.symlink(ogGlobals.OGCAC, mntdir) + except FileExistsError: + pass + else: + os.makedirs(mntdir, exist_ok=True) + + # Montar sistema de archivos. + try: + rc = subprocess.run(['mount', dev, mntdir], check=True).returncode + except subprocess.CalledProcessError: + try: + rc = subprocess.run(['mount', dev, mntdir, '-o', 'force,remove_hiberfile'], check=True).returncode + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ( + [], + ogGlobals.OG_ERR_PARTITION, + f"{disk}, {par}" + ) + return + + if 0 == rc: + pass + elif 14 == rc: + try: + subprocess.run (['ntfsfix', '-d', par], check=True) + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ( + [], + ogGlobals.OG_ERR_PARTITION, + f"{disk, par}" + ) + #return + else: + try: + subprocess.run (['mount', par, mntdir, '-o', 'ro'], check=True) + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ( + [], + ogGlobals.OG_ERR_PARTITION, + f"{disk, par}" + ) + #return + + # Aviso de montaje de solo lectura. + if ogIsReadonly(disk, par): + SystemLib.ogEcho("warning", f'ogMountFs: {ogGlobals.lang.MSG_MOUNTREADONLY}: "{disk}, {par}"') + else: + # Montar sistema de archivos ZFS (un ZPOOL no comienza por "/"). + subprocess.run(['zfs', 'mount', dev]) + + return mntdir + + + +#/** +# ogMountCdrom +#@brief Monta dispositivo óptico por defecto +#@return Punto de montaje +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Tipo de particion desconocido o no se puede montar. +#@version +#@author +#@date +#*/ ## +def ogMountCdrom(): + DEV = '/dev/cdrom' # Por defecto + outlines = subprocess.run (['mount'], capture_output=True, text=True).stdout.split ('\n') + mntdir = '' + for l in outlines: + items = l.split (' ') + if DEV == items[0]: + mntdir = items[2] + break + + if not mntdir: + mntdir = DEV.replace ('/dev', '/mnt') + os.makedirs (mntdir, exist_ok=True) + try: + subprocess.run (['mount', '-t', 'iso9660', DEV, mntdir], check=True) + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, 'cdrom') + return None + + return mntdir + + +#/** +# ogReduceFs int_ndisk int_nfilesys +#@brief Reduce el tamaño del sistema de archivos, sin tener en cuenta el espacio libre. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return int_tamañoKB - tamaño en KB +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Partición desconocida o no accesible. +#@warning En Windows, se borran los ficheros de hiberanción y de paginación. +#@warning El sistema de archivos se amplía al mínimo + 10%. +#@note Requisitos: *resize* +#*/ ## +def ogReduceFs (disk, par): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return + + # Redimensionar según el tipo de partición. + type = ogGetFsType (disk, par) + if type in ['EXT2', 'EXT3', 'EXT4']: + ogUnmount (disk, par) + rc = subprocess.run (['resize2fs', '-fpM', PART], capture_output=True, text=True).returncode + if rc: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk},{par}") + return None + elif 'BTRFS' == type: + mntdir = ogMount (disk, par) + # Calcular tamaño ocupado + 10%, redondeado + 1 (incluyendo letra de unidad). + btrfs_lines = subprocess.run (['btrfs', 'filesystem', 'show', mntdir], capture_output=True, text=True).stdout.splitlines() + for l in btrfs_lines: + if 'devid' not in l: continue + ## 'devid 2 size 8.89GiB used 1.00GiB path /dev/sda4' + devid_str, devid, size_str, size, used_str, used, path_str, path = l.split() + if PART != os.path.realpath (path): continue + (sz, unit) = re.search ('^([^A-Z]+)([A-Z])', used).groups() + sz = float (sz) * 1.1 + 1 + size = f'{str(sz)}{unit}' + subprocess.run (['btrfs', 'filesystem', 'resize', size, mntdir], capture_output=True, text=True) + break + elif type in ['REISERFS', 'REISER4']: + mntdir = ogMount (disk, par) + df_lines = subprocess.run (['df', '-k', mntdir], capture_output=True, text=True).stdout.splitlines() + for l in df_lines: + if 'Filesystem' in l: continue + fs, blocks, used, avail, use_pct, mntpt = l.split() + size = str (int (used) * 1.1) + ogUnmount (disk, par) + subprocess.run (['resize_reiserfs', f'-s{size}K', PART], input='y\n', capture_output=True, text=True) + break + elif type == 'NTFS': + ogUnmount (disk, par) + nr_lines = subprocess.run (['ntfsresize', '-fi', PART], capture_output=True, text=True).stdout.splitlines() + maxsize = None + size = None + for l in nr_lines: + if 'device size' in l: + maxsize = float (l.split()[3]) + if 'resize at' in l: + size = l.split()[4] + size = int ((int (size) * 1.1 / 1024 + 1) * 1024) + + if not maxsize and not size: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk},{par}') + return None + + import time + + extrasize = 0 + retval = 1 + while retval != 0 and size+extrasize < maxsize: + nr = subprocess.run (['ntfsresize', '-fns', str(size), PART], capture_output=True, text=True) + for l in nr.stdout.splitlines(): + if 'Needed relocations' not in l: continue + extrasize = int ((int (l.split()[3])*1.1/1024+1)*1024) + break + retval = nr.returncode + size += extrasize + if size < maxsize: + rc = subprocess.run (['ntfsresize', '-fs', str(size), PART], input='y\n', capture_output=True, text=True).returncode + if rc: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk},{par}") + return None + elif type in ['FAT32', 'FAT16', 'F2FS', 'JFS', 'NILFS2', 'XFS', 'EXFAT', 'HFS', 'HFSPLUS', 'UFS']: + pass + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f"{disk},{par}") + return None + + return ogGetFsSize (disk, par) + + +#/** +# ogUnlock int_ndisk int_npartition +#@see ogUnlockPartition +#*/ ## +def ogUnlock (disk, par): + return ogUnlockPartition (disk, par) + +#/** +# ogUnlockPartition int_ndisk int_npartition +#@brief Elimina el fichero de bloqueo para una particion. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@note El fichero de bloqueo se localiza en \c /var/lock/part, siendo \c part el dispositivo de la partición, sustituyendo el carácter "/" por "-". +#*/ ## +def ogUnlockPartition (disk, par): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return + + LOCKFILE = f"/var/lock/lock{PART.replace('/', '-')}" + if os.path.exists (LOCKFILE): + os.remove (LOCKFILE) + + +#/** +# ogUnmount int_ndisk int_npartition +#@see ogUnmountFs +#*/ ## +def ogUnmount (disk, par): + return ogUnmountFs (disk, par) + +#/** +# ogUnmountFs int_ndisk int_nfilesys +#@brief Desmonta un sistema de archivos. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@return Nada +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@warning La partición no está previamente montada o no se puede desmontar. +#*/ ## + +def ogUnmountFs(disk, par): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return + MNTDIR = ogGetMountPoint (disk, par) + + # Si está montada, desmontarla. + if MNTDIR: + # Error si la particion está bloqueada. + if ogIsLocked (disk, par): + SystemLib.ogRaiseError ( + [], + ogGlobals.OG_ERR_LOCKED, + f"{ogGlobals.lang.MSG_PARTITION}, {disk} {par}" + ) + return + + # Desmontar y borrar punto de montaje. + try: + subprocess.run(["umount", PART], check=True) + except subprocess.CalledProcessError: + SystemLib.ogEcho("warning", f'ogUnmountFs: {ogGlobals.lang.MSG_DONTUNMOUNT}: "{disk}, {par}"') + try: + os.rmdir(MNTDIR) + except: + try: + os.remove(MNTDIR) + except: + pass + return True + else: + SystemLib.ogEcho ([], "warning", f'{ogGlobals.lang.MSG_DONTMOUNT}: "{disk},{par}"') + return True + + +#/** +# ogUnmountAll int_ndisk +#@brief Desmonta todos los sistema de archivos de un disco, excepto el caché local. +#@param int_ndisk nº de orden del disco +#@return Nada +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@warning No se desmonta la partición marcada como caché local. +#*/ ## +def ogUnmountAll (disk): + DISK = DiskLib.ogDiskToDev (disk) + n = DiskLib.ogGetPartitionsNumber (disk) + if not n: return None + for PART in range (1, n+1): + if 'CACHE' != ogGetFsType (disk, PART): + ogUnmount (disk, PART) + + +#/** +# ogUnsetDirtyBit int_ndisk int_npart +#@brief Inhabilita el Dirty Bit del sistema de ficheros NTFS para evitar un CHKDSK en el primer arranque +#@param int_ndisk nº de orden del disco +#@param int_npart nº de orden de partición +#@return Nada +#@exception OG_ERR_FORMAT Formato incorrecto. +#*/ ## +def ogUnsetDirtyBit (disk, par): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return None + + TYPE = ogGetFsType (disk, par) + if 'NTFS' == TYPE: + ogUnmount (disk, par) + subprocess.run (['ntfsfix', '--clear-dirty', PART]) + + +#/** +# ogGetFreeSize int_disco int_partition str_SizeOutput +#@brief muestra informacion del tamaño total, datos y libre. +#@param int_ndisk nº de orden del disco +#@param int_npart nº de orden de partición +#@param str_unitSize unidad mostrada +#@return int_size:int_data:int_free +#@TODO Componer corretcamente esta función. +#@exception OG_ERR_FORMAT Formato incorrecto. +#*/ ## + +def ogGetFreeSize(disk, part, unit='KB'): + PART = DiskLib.ogDiskToDev (disk, part) + if not PART: return + + unit2factor = { + 'kb': 1.024 / 1, + 'mb': 1.024 / 1000, + 'gb': 1.024 / 1000000, + } + if unit.lower() not in unit2factor: + kk + factor = unit2factor[unit.lower()] + + particion = FileSystemLib.ogMount (disk, part) + if not particion: + kk + df = subprocess.run (['df'], capture_output=True, text=True).stdout + df_part = list (filter (lambda l: particion in l, df.splitlines())) + if not len (df_part): + kk + _, size, used, free, pct, mntpt = df_part[0].split() + return float (free) * factor diff --git a/client/lib/python3/ImageLib.py b/client/lib/python3/ImageLib.py new file mode 100644 index 0000000..2b5fc8c --- /dev/null +++ b/client/lib/python3/ImageLib.py @@ -0,0 +1,839 @@ +#!/usr/bin/python3 + +import shutil +import subprocess +import os +import os.path +import re +from pathlib import Path + +import DiskLib +import FileSystemLib +import SystemLib +import ogGlobals +import FileLib +import CacheLib +import NetLib + +## ProtocolLib.ogUcastSyntax() calls ogCreateImageSyntax() +## in ogCreateImageSyntax(), param2 may contain a pipe or may be empty +## if param2 is empty, then ogUcastSyntax(): +## - does a .split() +## - accesses the third element of the resulting array (ie. does "parts[2]") +## - promptly gets an IndexError exception +## +## param2 in ogCreateImageSyntax() only contains a pipe if 'mbuffer' is installed +## therefore, a hard dependency on mbuffer is created +## +## raise an Exception at import time if mbuffer is not present +if not shutil.which ('mbuffer'): + raise FileNotFoundError ('"mbuffer" utility must be present') + +#/** +#@file ImageLib.py +#@brief Librería o clase Image +#@class Image +#@brief Funciones para creación, restauración y clonación de imágenes de sistemas. +#@warning License: GNU GPLv3+ +#*/ + + +#/** +# ogCreateImageSyntax path_device path_filename [str_tool] [str_compressionlevel] +#@brief Genera una cadena de texto con la instrucción para crear un fichero imagen +#@param path_device dispositivo Linux del sistema de archivos +#@param path_fileneme path absoluto del fichero imagen +#@param [opcional] str_tool herrmaienta de clonacion [partimage, partclone, ntfsclone] +#@param [opcional] str_compressionlevel nivel de compresion. [0 -none-, 1-lzop-, 2-gzip] +#@return str_command - cadena con el comando que se debe ejecutar. +#@warning Salida nula si se producen errores. +#@TODO introducir las herramientas fsarchiver, dd +#*/ ## +#ogCreateImageSyntax /dev/sda1 /opt/opengnsys/images/prueba.img partclone lzop +#ogCreateImageSyntax /dev/sda1 /opt/opengnsys/images/prueba.img +def ogCreateImageSyntax (dev, imgfile, tool='partclone', level='gzip'): + + if 'ntfsclone' == tool: + param1 = f'ntfsclone --force --save-image -O - {dev}' + elif 'partimage' == tool or 'default' == tool: + param1 = f'partimage -M -f3 -o -d -B gui=no -c -z0 --volume=0 save {dev} stdout' + elif 'partclone' == tool: + disk, part = DiskLib.ogDevToDisk (dev).split() + fs = FileSystemLib.ogGetFsType (disk, part) + param1 = { + 'EXT2': 'partclone.extfs', + 'EXT3': 'partclone.extfs', + 'EXT4': 'partclone.extfs', + 'BTRFS': 'partclone.btrfs', + 'REISERFS': 'partclone.reiserfs', + 'REISER4': 'partclone.reiser4', + 'JFS': 'partclone.jfs', + 'XFS': 'partclone.xfs', + 'F2FS': 'partclone.f2fs', + 'NILFS2': 'partclone.nilfs2', + 'NTFS': 'partclone.ntfs', + 'EXFAT': 'partclone.exfat', + 'FAT16': 'partclone.fat', + 'FAT32': 'partclone.fat', + 'HFS': 'partclone.hfsp', + 'HFSPLUS': 'partclone.hfsp', + 'UFS': 'partclone.ufs', + 'VMFS': 'partclone.vmfs', + }.get (fs, 'partclone.imager') + dash_c = '-c' + if not shutil.which (param1): + param1 = 'partclone.dd' + # Algunas versiones de partclone.dd no tienen opción "-c". + out = subprocess.run (['partclone.dd', '--help'], capture_output=True, text=True).stdout + if ' -c' not in out: dash_c = '' + param1=f'{param1} -d0 -F {dash_c} -s {dev}' + else: + raise Exception (f'unknown tool "{tool}"') + + param2 = '| mbuffer -q -m 40M ' if shutil.which ('mbuffer') else ' ' + + param3 = { + 0: ' > ', + 'none': ' > ', + 1: ' | lzop > ', + 'lzop': ' | lzop > ', + 2: ' | gzip -c > ', + 'gzip': ' | gzip -c > ', + 3: ' | bzip -c > ', + 'bzip': ' | bzip -c > ', + }.get (level, ' > ') + + #print (f'param1 ({param1}) param2 ({param2}) param3 ({param3}) imgfile ({imgfile})') + if param1: return f'{param1} {param2} {param3} {imgfile}' + + +#/** +# ogRestoreImageSyntax path_filename path_device [str_tools] [str_compressionlevel] +#@brief Genera una cadena de texto con la instrucción para crear un fichero imagen +#@param path_device dispositivo Linux del sistema de archivos +#@param path_fileneme path absoluto del fichero imagen +#@param [opcional] str_tools herrmaienta de clonacion [partimage, partclone, ntfsclone] +#@param [opcional] str_compressionlevel nivel de compresion. [0 -none-, 1-lzop-, 2-gzip] +#@return cadena con el comando que se debe ejecutar. +#@exception OG_ERR_FORMAT formato incorrecto. +#@warning En pruebas iniciales +#@TODO introducir las herramientas fsarchiver, dd +#@TODO introducir el nivel de compresion gzip +#*/ ## +#ogRestoreImageSyntax /opt/opengnsys/images/prueba.img /dev/sda1 [partclone] [lzop] +def ogRestoreImageSyntax (imgfile, part, tool=None, level=None): + if not os.path.exists (imgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile) + ## original bash code is broken: 'return' is never called + #return + + if tool is None or level is None: + infoimg = ogGetImageInfo (imgfile) + if not infoimg: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'no image {imgfile}') + ## original bash code is broken: 'return' is never called + #return + try: + tool, level = infoimg.split (':')[0:2] + except: + tool, level = '', '' + return ogRestoreImageSyntax (imgfile, part, tool, level) + + tool = tool.lower() + level = level.lower() + compressor = { + 0: ' ', + 'none': ' ', + 1: ' lzop -dc ', + 'lzop': ' lzop -dc ', + 2: ' gzip -dc ', + 'gzip': ' gzip -dc ', + 3: ' bzip -dc ', + 'bzip': ' bzip -dc ', + }.get (level, '') + #print (f'tool ({tool}) level ({level}) compressor ({compressor})') + if compressor == '': + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'Compressor no valid {level}') + ## original bash code is broken: 'return' is never called + #return + + mbuffer = '| mbuffer -q -m 40M ' if shutil.which ('mbuffer') else ' ' + #print (f'mbuffer ({mbuffer})') + if 'ntfsclone' == tool: + tool = f'| ntfsclone --restore-image --overwrite {part} -' + elif 'partimage' == tool: + tool = f'| partimage -f3 -B gui=no restore {part} stdin' + elif 'partclone' in tool: + # -C para que no compruebe tamaños + tool = f'| partclone.restore -d0 -C -I -o {part}' + elif 'dd' == tool: + tool = f'| pv | dd conv=sync,noerror bs=1M of={part}' + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'Tools imaging no valid {tool}') + ## original bash code is broken: 'return' is never called + #return + #print (f'tool ({tool})') + + return f'{compressor} {imgfile} {mbuffer} {tool}'.strip() + + + + +#/** +# ogCreateDiskImage int_ndisk str_repo path_image [str_tools] [str_compressionlevel] +#@brief Crea una imagen (copia de seguridad) de un disco completo. +#@param int_ndisk nº de orden del disco +#@param str_repo repositorio de imágenes (remoto o caché local) +#@param path_image camino de la imagen (sin extensión) +#@return (nada, por determinar) +#@note repo = { REPO, CACHE } +#@note Esta primera versión crea imágenes con dd comprimidas con gzip. +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. +#@exception OG_ERR_LOCKED particion bloqueada por otra operación. +#@exception OG_ERR_IMAGE error al crear la imagen del sistema. +#@warning En pruebas iniciales +#@todo Gestión de bloqueos de disco +#@todo Comprobar si debe desmontarse la caché local +#@todo Comprobar que no se crea la imagen en el propio disco +#*/ ## + + +#/** +# ogCreateImage int_ndisk int_npartition str_repo path_image [str_tools] [str_compressionlevel] +#@brief Crea una imagen a partir de una partición. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@param str_repo repositorio de imágenes (remoto o caché local) +#@param path_image camino de la imagen (sin extensión) +#@param [opcional] str_tools herrmaienta de clonacion [partimage, partclone, ntfsclone] +#@param [opcional] str_compressionlevel nivel de compresion. [0 -none-, 1-lzop-, 2-gzip] +#@return (nada, por determinar) +#@note repo = { REPO, CACHE } +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. +#@exception OG_ERR_PARTITION partición no accesible o no soportada. +#@exception OG_ERR_LOCKED particion bloqueada por otra operación. +#@exception OG_ERR_IMAGE error al crear la imagen del sistema. +#@todo Comprobaciones, control de errores, definir parámetros, etc. +#*/ ## +def ogCreateImage (disk, par, container, imgfile, tool='partclone', level='gzip'): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return None + + if FileSystemLib.ogIsLocked (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_ERR_LOCKED} {disk}, {par}') + return None + + imgtype = 'img' # Extensión genérica de imágenes. + imgdir = FileLib.ogGetParentPath (src=container, file=imgfile) + if not imgdir: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{container} {imgfile}') + return None + + bn = os.path.basename (imgfile) + IMGFILE = f'{imgdir}/{bn}.{imgtype}' + if ogIsImageLocked (IMGFILE): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_IMAGE} {container}, {imgfile}') + return None + +# Generar la instruccion a ejecutar antes de aplicar los bloqueos. + program = ogCreateImageSyntax (PART, IMGFILE, tool=tool, level=level) +# Desmontar partición, bloquear partición e imagen. + FileSystemLib.ogUnmount (disk, par) + if not FileSystemLib.ogLock (disk, par): + return None + if not ogLockImage (container, f'{imgfile}.{imgtype}'): + return None + +# Crear Imagen. + #trap + print (f'nati program ({program})') + p = subprocess.run (program, shell=True, check=True) + errcode = p.returncode + if 0 == errcode: + i = ogGetImageInfo (IMGFILE) + h = NetLib.ogGetHostname() + with open (f'{IMGFILE}.info', 'w') as fd: + fd.write (f'{i}:{h}\n') + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'{disk} {par} {IMGFILE}') + if os.path.exists (IMGFILE): + os.unlink (IMGFILE) + + FileSystemLib.ogUnlock (disk, par) + ogUnlockImage (container, f'{imgfile}.{imgtype}') + return not errcode ## reverse to indicate success + + +#/** +# ogCreateMbrImage int_ndisk str_repo path_image +#@brief Crea una imagen a partir del sector de arranque de un disco. +#@param int_ndisk nº de orden del disco +#@param str_repo repositorio de imágenes (remoto o caché local) +#@param path_image camino de la imagen (sin extensión) +#@return (nada, por determinar) +#@note repo = { REPO, CACHE } +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. +#@exception OG_ERR_IMAGE error al crear la imagen del sistema. +#*/ ## + + +#/** +# ogCreateBootLoaderImage int_ndisk str_repo path_image +#@brief Crea una imagen del boot loader a partir del sector de arranque de un disco. +#@param int_ndisk nº de orden del disco +#@param str_repo repositorio de imágenes (remoto o caché local) +#@param path_image camino de la imagen (sin extensión) +#@return (nada, por determinar) +#@note repo = { REPO, CACHE } +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. +#@exception OG_ERR_IMAGE error al crear la imagen del sistema. +#*/ ## + +#/** +# ogGetSizeParameters int_num_disk int_num_part str_repo [monolit|sync|diff] +#@brief Devuelve el tamaño de los datos de un sistema de ficheros, el espacio necesario para la imagen y si cabe en el repositorio elegido. +#@param int_disk numero de disco +#@param int_part numero de particion +#@param str_repo repositorio de imágenes { REPO, CACHE } +#@param str_imageName Nombre de la imagen +#@param str_imageType Tipo de imagen: monolit (por defecto), sync o diff. (parametro opcional) +#@return SIZEDATA SIZEREQUIRED SIZEFREE ISENOUGHSPACE +#@note si str_imageType= diff necesario /tmp/ogimg.info, que es creado por ogCreateInfoImage. +#@note para el tamaño de la imagen no sigue enlaces simbólicos. +#@exception OG_ERR_FORMAT formato incorrecto. +#*/ ## +#SIZEDATA, SIZEREQUIRED, SIZEFREE, ISENOUGHSPACE = ogGetSizeParameters (1, 1, 'REPO', 'myimg') +def ogGetSizeParameters (disk, par, repo, imgname, imgtype=None): + repo = repo.upper() + ## imgtype se soporta como parametro pero se ignora + + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f'{disk} {par}') + return None + + #if [ "$IMGTYPE" == "_DIFF_" ]; then cosas + #else: + sizedata = None + df_out = subprocess.run (['df', '-k'], capture_output=True, text=True).stdout + for l in df_out.splitlines(): + if (re.search (f'{mntdir}$', l)): + sizedata = int (l.split()[2]) + break + if sizedata is None: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'sizedata is None') + return None + + #if [ "$IMGTYPE" == "_SYNC_" -o "$IMGTYPE" == "_DIFF_" ]; then cosas + #else: + factorgzip=55/100 + factorlzop=65/100 + sizerequired = sizedata * factorlzop + + #Comprobar espacio libre en el contenedor. + sizefree = None + if 'CACHE' == repo: + CACHEPART = CacheLib.ogFindCache() + if not CACHEPART: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTCACHE, '') + return None + cache_disk, cache_par = CACHEPART.split() + sizefree = FileSystemLib.ogGetFreeSize (cache_disk, cache_par) + if 'REPO' == repo: + df_out = subprocess.run (['df', '-k'], capture_output=True, text=True).stdout + for l in df_out.splitlines(): + if (re.search (f'{ogGlobals.OGIMG}', l)): + sizefree = int (l.split()[3]) + break + if sizefree is None: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'sizefree is None') + return None + +# Comprobamos si existe una imagen con el mismo nombre en $REPO +# En sincronizadas restamos tamaño de la imagen y en monoloticas de la .ant + #case "${IMGTYPE}" in blah blah + #*) + imgext = 'img.ant' + + imgdir = FileLib.ogGetParentPath (src=repo, file=f'/{imgname}') + bn = os.path.basename (f'/{imgname}') + imgfile = FileLib.ogGetPath (file=f'{imgdir}/{bn}.{imgext}') + + if not imgfile: + imgsize = 0 + else: + ls_out = subprocess.run (['ls', '-s', imgfile], capture_output=True, text=True).stdout + imgsize = int (ls_out.split()[0]) + + sizefree = sizefree + imgsize + + if sizerequired < sizefree: + isenoughspace = True + else: + isenoughspace = False + + return sizedata, sizerequired, sizefree, isenoughspace + +#/** +# ogIsImageLocked [str_repo] path_image +#@brief Comprueba si una imagen está bloqueada para uso exclusivo. +#@param str_repo repositorio de imágenes (opcional) +#@param path_image camino de la imagen (sin extensión) +#@return Código de salida: 0 - bloqueado, 1 - sin bloquear o error. +#@note repo = { REPO, CACHE } +#@exception OG_ERR_FORMAT formato incorrecto. +#*/ ## +#ogIsImageLocked ('/opt/opengnsys/images/aula1/win7.img') +#ogIsImageLocked ('REPO', '/aula1/win7.img') +def ogIsImageLocked (container=None, imgfile=None): + if container and imgfile: + p = FileLib.ogGetPath (src=container, file=f'{imgfile}.lock') + elif imgfile: + p = FileLib.ogGetPath (file=f'{imgfile}.lock') + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'{container} {imgfile}') + return + return os.path.exists (p) + + +#/** +# ogLockImage [str_repo] path_image +#@brief Bloquea una imagen para uso exclusivo. +#@param str_repo repositorio de imágenes (opcional) +#@param path_image camino de la imagen (sin extensión) +#@return Nada. +#@note Se genera un fichero con extensión .lock +#@note repo = { REPO, CACHE } +#@exception OG_ERR_FORMAT formato incorrecto. +#*/ ## +def ogLockImage (container=None, imgfile=None): + if not imgfile: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, '') + return None + + if container: + imgdir = FileLib.ogGetParentPath (src=container, file=imgfile) + else: + imgdir = FileLib.ogGetParentPath (file=imgfile) + + try: + bn = os.path.basename (imgfile) + open (f'{imgdir}/{bn}.lock', 'w').close() + return True + except: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTWRITE, f'{container} {imgfile}') + return None + + +#/** +# ogRestoreDiskImage str_repo path_image int_npartition +#@brief Restaura (recupera) una imagen de un disco completo. +#@param str_repo repositorio de imágenes o caché local +#@param path_image camino de la imagen +#@param int_ndisk nº de orden del disco +#@return (por determinar) +#@warning Primera versión en pruebas +#@todo Gestionar bloqueos de disco +#@todo Comprobar que no se intenta restaurar de la caché sobre el mismo disco +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados. +#@exception OG_ERR_LOCKED partición bloqueada por otra operación. +#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema. +#@exception OG_ERR_IMGSIZEPARTITION Tamaño de la particion es menor al tamaño de la imagen. +#*/ ## + + +#/** +# ogRestoreImage str_repo path_image int_ndisk int_npartition +#@brief Restaura una imagen de sistema de archivos en una partición. +#@param str_repo repositorio de imágenes o caché local +#@param path_image camino de la imagen +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return (por determinar) +#@exception OG_ERR_FORMAT 1 formato incorrecto. +#@exception OG_ERR_NOTFOUND 2 fichero de imagen o partición no detectados. +#@exception OG_ERR_PARTITION 3 # Error en partición de disco. +#@exception OG_ERR_LOCKED 4 partición bloqueada por otra operación. +#@exception OG_ERR_IMAGE 5 error al restaurar la imagen del sistema. +#@exception OG_ERR_IMGSIZEPARTITION 30 Tamaño de la particion es menor al tamaño de la imagen. +#@todo Comprobar incongruencias partición-imagen, control de errores, definir parámetros, caché/repositorio, etc. +#*/ ## +#ogRestoreImage ('REPO', '/aula1/win7', '1', '1') +def ogRestoreImage (repo, imgpath, disk, par): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {disk} {par}') + return None + + imgtype = 'img' + imgfile = FileLib.ogGetPath (repo, f'{imgpath}.{imgtype}') + if not os.path.exists (imgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {disk} {par}') + return None + + if not ogGetImageInfo (imgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f' {repo} {imgpath}') + return None + + # Error si la imagen no cabe en la particion. + imgsize = ogGetImageSize (repo, imgpath) + if not imgsize: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f' {repo} {imgpath}') + return None + if not FileSystemLib.ogMount (disk, par): + FileSystemLib.ogFormat (disk, par) + partsize = DiskLib.ogGetPartitionSize (disk, par) + if float (imgsize) > float (partsize): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMGSIZEPARTITION, f' {partsize} < {imgsize}') + return None + + if ogIsImageLocked (container=None, imgfile=imgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_IMAGE} {repo}, {imgpath}.{imgtype}') + return None + + if FileSystemLib.ogIsLocked (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_LOCKED, f'{ogGlobals.lang.MSG_PARTITION} {disk}, {par}') + return None + + program = ogRestoreImageSyntax (imgfile, PART) + + if not FileSystemLib.ogUnmount (disk, par): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_PARTITION, f' {disk} {par}') + return None + + if not FileSystemLib.ogLock (disk, par): + print (f'not FileSystemLib.ogLock()') + return None + + rc = None + try: + #print (f'nati: ogRestoreImage: running ({program})') + p = subprocess.run (program, shell=True, capture_output=True, text=True) + rc = p.returncode + #print (f'nati: ogRestoreImage: rc ({rc}) stdout ({p.stdout}) stderr ({p.stderr})') + if not rc: + SystemLib.ogRaiseError ([], ogGlobalsOG_ERR_IMAGE, f'{imgfile}, {disk}, {par}') + except: + pass + finally: + FileSystemLib.ogUnlock (disk, par) + + return rc + + + +#/** +# ogRestoreMbrImage str_repo path_image int_ndisk +#@brief Restaura la imagen del sector de arranque de un disco. +#@param str_repo repositorio de imágenes o caché local +#@param path_image camino de la imagen +#@param int_ndisk nº de orden del disco +#@return (por determinar) +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados. +#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema. +#*/ ## + + +#/** +# ogRestoreBootLoaderImage str_repo path_image int_ndisk +#@brief Restaura la imagen del boot loader del sector de arranque de un disco. +#@param str_repo repositorio de imágenes o caché local +#@param path_image camino de la imagen +#@param int_ndisk nº de orden del disco +#@return (por determinar) +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados. +#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema. +#*/ ## + +#/** +# ogUnlockImage [str_repo] path_image +#@brief Desbloquea una imagen con uso exclusivo. +#@param str_repo repositorio de imágenes (opcional) +#@param path_image camino de la imagen (sin extensión) +#@return Nada. +#@note repo = { REPO, CACHE } +#@note Se elimina el fichero de bloqueo con extensión .lock +#@exception OG_ERR_FORMAT formato incorrecto. +#*/ ## +#ogUnlockImage REPO /cucu.img +def ogUnlockImage (container=None, imgfile=None): + f = f'{imgfile}.lock' + if container: + p = FileLib.ogGetPath (src=container, file=f) + else: + p = FileLib.ogGetPath (file=f) + + if os.path.exists (p): + os.unlink (p) + + +#/** +# ogGetImageInfo filename +#@brief muestra información sobre la imagen monolitica. +#@param 1 filename path absoluto del fichero imagen +#@return cadena compuesta por clonacion:compresor:sistemaarchivos:tamañoKB +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero no encontrado. +#@exception OG_ERR_IMAGE "Image format is not valid $IMGFILE" +#@warning En pruebas iniciales +#@TODO Definir sintaxis de salida (herramienta y compresor en minuscula) +#@TODO Arreglar loop para ntfsclone +#@TODO insertar parametros entrada tipo OG +#*/ ## +#ogGetImageInfo /opt/opengnsys/images/prueba.img ==> PARTCLONE:LZOP:NTFS:5642158" +def ogGetImageInfo (imgfile): + if not os.path.exists (imgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile) + return + + imgdetect = False + filehead = f'/tmp/{os.path.basename (imgfile)}.infohead' + compressor = subprocess.run (['file', imgfile], capture_output=True, text=True).stdout.split()[1] + if compressor not in ['gzip', 'lzop']: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'Image format is not valid {imgfile}') + return + + ## original bash idiom is: $($COMPRESSOR -dc $IMGFILE 2>/dev/null | head -n 40 > $FILEHEAD) || ogRaiseError + ## the purpose of which I can't fully comprehend + #print (f'shelling out "{compressor} -dc {imgfile} |head -n 40 > {filehead}"') + if subprocess.run (f'{compressor} -dc {imgfile} |head -n 40 > {filehead}', shell=True).returncode: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'Image format is not valid {imgfile}') + return + + tools = fs = size = None + + if False == imgdetect: + lc_all = os.getenv ('LC_ALL') + os.environ['LC_ALL'] = 'C' + partclone_info = subprocess.run (['partclone.info', filehead], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout + #partclone_info = subprocess.run (['cat', '/tmp/foo-partclone'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout + ## sacado de un email de alberto garcía uma.es + #Partclone v0.3.13 http://partclone.org + #Unknown mode + #File system: NTFS + #Device size: 29.2 GB = 7138019 Blocks + #Space in use: 26.6 GB = 6485355 Blocks + #Free Space: 2.7 GB = 652664 Blocks + #Block size: 4096 Byte + # + #image format: 0002 + #created on a: 64 bits platform + #with partclone: v0.3.13 + #bitmap mode: BIT + #checksum algo: CRC32 + #checksum size: 4 + #blocks/checksum: 256 + if lc_all is not None: + os.environ["LC_ALL"] = lc_all + else: + del os.environ["LC_ALL"] + + if 'size' in partclone_info: + tools = 'PARTCLONE' + m = re.search (r'File system *: *(\S+)', partclone_info) + fs = m.group(1) if m else '' + + sizefactor = 1000000 if 'GB' in partclone_info else 1024 + m = re.search (r'Device size *: *(\S+)', partclone_info) + size = float (m.group(1)) if m else 0 + size = int (size * sizefactor) + + ## why is this? + #if fs in ['HFS', 'HFSPLUS', 'FAT32']: + # #FSPLUS=$(echo $PARTCLONEINFO | awk '{gsub(/\: /,"\n"); print toupper($9);}') + # fsplus = 'PLUS' + # if fsplus: # fs += fsplus ## 'HFS' -> 'HFSPLUS' + + imgdetect = True + + if False == imgdetect and not os.path.exists ('/dev/loop2'): + filehead_contents = Path (filehead).read_bytes() + if b'ntfsclone-image' in filehead_contents: + #print (f'shelling out "cat {filenead} | ntfsclone --restore --overwrite /dev/loop2 - 2>&1"') + ntfscloneinfo = subprocess.run (f'cat {filenead} | ntfsclone --restore --overwrite /dev/loop2 - 2>&1', shell=True, capture_output=True, text=True).stdout + #ntfscloneinfo = subprocess.run (['cat', '/tmp/foo-ntfsclone'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout + ## sacado de claude 3 haiku + #ntfsclone v2023.4.0 (libntfs-3g) + #NTFS volume version: 3.1 + #Cluster size: 4096 bytes + #Image volume size: 104857600 bytes (105 MB) + #Space in use: 52428800 bytes (52 MB) + #Reading and restoring NTFS... + #100.00 percent completed + #Syncing ... + #Successfully cloned image to device '/dev/loop2'. + else: + ntfscloneinfo = '' + + if 'ntfsclone' in ntfscloneinfo: + tools = 'NTFSCLONE' + m = re.search (r'Image volume size *: *(\S+)', ntfscloneinfo) + size = float (m.group(1))/1000 if m else 0 + fs = 'NTFS' + imgdetect = True + + if False == imgdetect: + partimageinfo = subprocess.run (['partimage', '-B', 'gui=no', 'imginfo', filehead], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout + #partimageinfo = subprocess.run (['cat', '/tmp/foo-partimage'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout + ## sacado de un email de alberto garcía uma.es + #Volume number:.........0 + #Volume size:...........1,27 MiB + #Compression level: ....0 -> ninguno + #Identificator:.........12442509728668372730=ACACACACCB9ECEFA + #Filesystem:............ntfs + #Description:...........Sin descripcion + #Original device:......./dev/nvme0n1p2 + #Original filepath:.... stdout + #Flags:.................0: Bandera sin activar + #Creation date:.........Mon Nov 11 21:00:22 2024 + #Partition size:........476,84 GiB + #Hostname:..............ING-LTR-083 + #Compatible Version:....0.6.1 + #Encryption algorithm:..0 -> ninguno + #MBR saved count:.......0 + partimageinfo = re.sub (r':\s*\.+', ' : ', partimageinfo) + if 'Partition' in partimageinfo: + tools = 'PARTIMAGE' + m = re.search (r'Filesystem *: *(\S+)', partimageinfo) + fs = m.group(1).upper() if m else '' + + m = re.search (r'Partition size *: *(\S+)', partimageinfo) + size = m.group(1) if m else '' + size = re.sub (r' [MGT]i?B$', '', size) + size = float (size.replace (',', '.')) + size = int (size*1024*1024) + + imgdetect = True + if 'boot sector' in subprocess.run (['file', filehead], capture_output=True, text=True).stdout: + tools = 'partclone.dd' + fs = '' + size = 0 + imgdetect = True + + if not tools or not compressor or False == imgdetect: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_IMAGE, f'Image format is not valid {imgfile}') + return + + compressor = compressor.upper() + return ':'.join ([tools, compressor, fs, str (size)]) + +#/** +# ogGetImageProgram str_REPO str_imagen +#@brief muestra información sobre la imagen monolitica. +#@see ogGetImageInfo +#@param 1 REPO o CACHE contenedor de la imagen +#@param 2 filename nombre de la imagen sin extension +#@return nombre del programa usado para generar la imagen +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero no encontrado. +#@note ogGetImageProgram REPO imagenA -> partclone +#*/ ## + +#ogGetImageProgram ('REPO', 'prueba') ==> 'PARTCLONE' +def ogGetImageProgram (container, filename): + imgfile = FileLib.ogGetPath (container, f'{filename}.img') + if not os.path.exists (imgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile) + return None + i = ogGetImageInfo (imgfile) + return i.split (':')[0] + +#/** +# ogGetImageCompressor str_REPO str_imagen +#@brief muestra información sobre la imagen monolitica. +#@see ogGetImageInfo +#@param 1 REPO o CACHE contenedor de la imagen +#@param 2 filename nombre de la imagen sin extension +#@return tipo de compresión usada al generar la imagen +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero no encontrado. +#@note ogGetImageCompressor REPO imagenA -> lzop +#*/ ## + +#ogGetImageCompressor ('REPO', 'prueba') ==> 'LZOP' +def ogGetImageCompressor (container, filename): + imgfile = FileLib.ogGetPath (container, f'{filename}.img') + if not os.path.exists (imgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile) + return None + i = ogGetImageInfo (imgfile) + return i.split (':')[1] + + +#/** +# ogGetImageType str_REPO str_imagen +#@brief muestra información sobre el sistema de archivos de imagen monolitica. +#@see ogGetImageInfo +#@param 1 REPO o CACHE contenedor de la imagen +#@param 2 filename nombre de la imagen sin extension +#@return tipo de compresión usada al generar la imagen +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero no encontrado. +#@note ogGetImageType REPO imagenA -> NTFS +#*/ ## +#ogGetImageType ('REPO', 'imgprueba') ==> 'NTFS' +#ogGetImageType ('CACHE', 'testimg') ==> 'EXTFS' +def ogGetImageType (repo, imgname): + imgfile = FileLib.ogGetPath (src=repo, file=f'{imgname}.img') + if not os.path.exists (imgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile) + return None + + i = ogGetImageInfo (imgfile) + return i.split (':')[2] + + + +#/** +# ogGetImageSize str_REPO str_imagen +#@brief muestra información sobre el tamaño (KB) del sistema de archivos de imagen monolitica. +#@see ogGetImageInfo +#@param 1 REPO o CACHE contenedor de la imagen +#@param 2 filename nombre de la imagen sin extension +#@return tipo de compresión usada al generar la imagen +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero no encontrado. +#@note ogGetImagesize REPO imagenA -> 56432234 > Kb +#*/ ## +#ogGetImageSize ('REPO', 'prueba') ==> '5642158' +def ogGetImageSize (repo, imgname): + imgfile = FileLib.ogGetPath (src=repo, file=f'{imgname}.img') + if not os.path.exists (imgfile): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, imgfile) + return None + + i = ogGetImageInfo (imgfile) + return i.split (':')[3] + + +#/** +# ogCreateGptImage int_ndisk str_repo path_image +#@brief Crea una imagen de la tabla de particiones GPT de un disco. +#@param int_ndisk nº de orden del disco +#@param str_repo repositorio de imágenes (remoto o caché local) +#@param path_image camino de la imagen (sin extensión) +#@return (nada, por determinar) +#@note repo = { REPO, CACHE } +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero o dispositivo no encontrado. +#@exception OG_ERR_IMAGE error al crear la imagen del sistema. +#*/ ## + +#/** +# ogRestoreGptImage str_repo path_image int_ndisk +#@brief Restaura la imagen de la tabla de particiones GPT de un disco. +#@param str_repo repositorio de imágenes o caché local +#@param path_image camino de la imagen +#@param int_ndisk nº de orden del disco +#@return (por determinar) +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTFOUND fichero de imagen o partición no detectados. +#@exception OG_ERR_IMAGE error al restaurar la imagen del sistema. +#*/ ## diff --git a/client/lib/python3/InventoryLib.py b/client/lib/python3/InventoryLib.py new file mode 100644 index 0000000..2269af3 --- /dev/null +++ b/client/lib/python3/InventoryLib.py @@ -0,0 +1,531 @@ +#/** +#@file InventoryLib.py +#@brief Librería o clase Inventory +#@class Inventory +#@brief Funciones para recogida de datos de inventario de hardware y software de los clientes. +#@warning License: GNU GPLv3+ +#*/ + +import platform +import sys +import os +import subprocess +import re +import json +import shutil +import glob +import plistlib +#import bsddb + +import ogGlobals +import SystemLib +import FileSystemLib +import RegistryLib +import FileLib + + +#/** +# ogGetArch +#@brief Devuelve el tipo de arquitectura del cliente. +#@return str_arch - Arquitectura (i386 para 32 bits, x86_64 para 64 bits). +#*/ +def ogGetArch(): + if os.path.isdir ('/lib64'): + return 'x86_64' + else: + return 'i386' + + +#/** +# ogGetOsType int_ndisk int_npartition +#@brief Devuelve el tipo del sistema operativo instalado. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return OSType - Tipo de sistema operativo. +#@see ogGetOsVersion +#*/ ## +def ogGetOsType(disk, partition): + try: + os_version = ogGetOsVersion(disk, partition) + if os_version: + return os_version.split(":", 1)[0] + else: + return None + except Exception as e: + print(f"Error en ogGetOsType: {e}") + return "Unknown" + + +#/** +# ogGetOsUuid int_ndisk int_nfilesys +#@brief Devuelve el UUID del sistema operativo instalado en un sistema de archivos. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden de la partición +#@return str_uuid - UUID del sistema operativo. +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositiv +#*/ ## +def ogGetOsUuid (disk, par): + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: return None + +# Obtener UUID según el tipo de sistema operativo. + os_type = ogGetOsType (disk, par) + if 'Linux' == os_type: + # Leer el UUID del sistema de ficheros raíz o el fichero de identificador. + uuid = subprocess.run (['findmnt', '-no', 'UUID', mntdir], capture_output=True, text=True).stdout.strip() + if not uuid: + uuid = open (os.path.join (mntdir, 'etc', 'machine-id')).read().strip() + return uuid + elif 'Windows' == os_type: + # Leer identificador en clave de registro. + uuid = RegistryLib.ogGetRegistryValue (mntdir, 'SOFTWARE', r'\Microsoft\Cryptography\MachineGuid') + return uuid + + +#/** +# ogGetSerialNumber +#@brief Obtiene el nº de serie del cliente. +#*/ ## +def ogGetSerialNumber(): + SERIALNO = subprocess.check_output(["dmidecode", "-s", "system-serial-number"]).decode().strip() + SERIALNO = re.sub(r"(not specified|to be filled|invalid entry|default string)", "", SERIALNO, flags=re.IGNORECASE) + SERIALNO = SERIALNO.replace(" ", "") + SERIALNO = SERIALNO[:25] if len(SERIALNO) > 25 else SERIALNO + if SERIALNO: return SERIALNO + return None + + +#/** +# ogIsEfiActive +#@brief Comprueba si el sistema tiene activo el arranque EFI. +#*/ ## +def ogIsEfiActive(): + return os.path.isdir("/sys/firmware/efi") + + +#/** +# ogListHardwareInfo +#@brief Lista el inventario de hardware de la máquina cliente. +#@return TipoDispositivo:Modelo (por determinar) +#@warning Se ignoran los parámetros de entrada. +#@note TipoDispositivo = { bio, boa, bus, cha, cdr, cpu, dis, fir, mem, mod, mul, net, sto, usb, vga } +#@note Requisitos: dmidecode, lshw, awk +#*/ ## +def ogListHardwareInfo(): + ret = '' + + SystemLib.ogEcho ([], 'info', ogGlobals.lang.MSG_HARDWAREINVENTORY) + # Ejecutar dmidecode y obtener tipo de chasis + dmi_out = subprocess.run (['dmidecode', '-s', 'chassis-type'], capture_output=True, text=True).stdout + dmi_out = '\n'.join ([ x for x in dmi_out.splitlines() if 'Other' not in x ]) + ret += f'cha={dmi_out}\n' + + if os.path.exists ('/sys/firmware/efi'): + ret += f'boo=UEFI\n' + else: + ret += f'boo=BIOS\n' + + awk_script = r''' + BEGIN {type="mod";} + /product:/ {sub(/ *product: */,""); prod=$0;} + /vendor:/ {sub(/ *vendor: */,""); vend=$0;} + /version:/ {sub(/ *version: */,"v.");vers=$0;} + /size:/ {size=$2;} + /clock:/ {clock=$2;} + /slot:/ {sub(/ *slot: */,""); slot=$0;} + /\*-/ {if (type=="mem"){ + if (size!=""){ + numbank++; + print type"="vend,prod,size,clock" ("slot")";} + }else{ + if (type=="totalmem"){ + if (size!=""){ + totalmemory="mem="size;} + }else{ + if (type!="" && prod!=""){ + if (prod=="v."vers) + vers=""; + print type"="vend,prod,size,vers;} } + } + type=prod=vend=vers=size=clock=slot="";} + $1~/-core/ {type="boa";} + $1~/-firmware/ {type="bio";} + $1~/-cpu/ {type="cpu";} + $1~/-bank/ {type="mem";} + $1~/-memory/ {type="totalmem";} + $1~/-ide/ {type="ide";} + $1~/-storage/ {type="sto";} + $1~/-disk/ {type="dis";} + $1~/-cdrom/ {type="cdr";} + $1~/-display/ {type="vga";} + $1~/-network/ {type="net";} + $1~/-multimedia/ {type="mul";} + $1~/-usb/ {type="usb";} + $1~/-firewire/ {type="fir";} + $1~/-serial/ {type="bus";} + END {if (type!="" && prod!="") + print type"="vend,prod,size,vers; + if (length(numbank)==0 && length(totalmemory)>=4) + print totalmemory; } + ''' + lshw_out = subprocess.run (['lshw'], capture_output=True, text=True).stdout + awk_out = subprocess.run (['awk', awk_script], input=lshw_out, capture_output=True, text=True).stdout + + ret += awk_out + + return ret + + +#/** +# ogListSoftware int_ndisk int_npartition +#@brief Lista el inventario de software instalado en un sistema operativo. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@return programa versión ... +#@warning Se ignoran los parámetros de entrada. +#@note Requisitos: ... +#@todo Detectar software en Linux +#*/ ## +def ogListSoftware (disk, par): + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: return None + ostype = ogGetOsType (disk, par) + if not ostype: return None + + apps = [] + + if 'Linux' == ostype: + # Procesar paquetes dpkg. + pkgdir = f'{mntdir}/var/lib/dpkg' + if os.path.exists (pkgdir): + status_file = os.path.join(pkgdir, "status") + awk_script = ''' + /Package:/ {if (pack!="") print pack,vers; + sub(/-dev$/,"",$2); + pack=$2} + /Version:/ {sub(/^.*:/,"",$2); sub(/-.*$/,"",$2); + vers=$2} + /Status:/ {if ($2!="install") pack=vers=""} + END {if (pack!="") print pack,vers} + ''' + awk_out = subprocess.run (['awk', awk_script, status_file], capture_output=True, text=True).stdout + apps = awk_out.splitlines() + + # Procesar paquetes RPM. + pkgdir = f'{mntdir}/var/lib/rpm' + if os.path.exists (pkgdir): + if shutil.which ('rpm'): + for f in glob.glob (f'{pkgdir}/__db.*'): + os.unlink (f) + rpm_out = subprocess.run (['rpm', '--dbpath', pkgdir, '-qa', '--qf', '%{NAME} %{VERSION}\n'], capture_output=True, text=True).stdout + for l in rpm_out.splitlines(): + words = l.split() + if (not re.search ('-devel$', words[0])): + words[1] = re.sub ('-.*', '', words[1]) + apps.append (' '.join (words)) + for f in glob.glob (f'{pkgdir}/__db.*'): + os.unlink (f) + else: + pass + #db = bsddb.hashopen (f'{pkgdir}/Name', 'r'); + #for k in db.keys(): + # apps.append (re.sub ('-devel$', '', k)) + + # Procesar paquetes pacman. + pkgdir = f'{mntdir}/var/lib/pacman/local' + if os.path.exists (pkgdir): + for f in glob.glob (f'{pkgdir}/*'): + if '-' not in f: continue + idx = f[0:f.rfind ('-')].rfind ('-') ## index of 2nd-to-last dash + apps.append (f[0:idx] + ' ' + f[idx+1:]) + # Procesar aplicaciones Snappy. + pkgdir = f'{mntdir}/snap' + out = '' + awk_script = ''' + /name:/ {pack=$2} + /version:/ {vers=$2} + END {if (pack!="") print pack,"(snap)",vers} + ''' + files = subprocess.run (['find', f'{pkgdir}/*/current/meta', '-name', 'snap.yaml'], capture_output=True, text=True).stdout.splitlines() + for f in files: + awk_out = subprocess.run (['awk', awk_script, f], capture_output=True, text=True).stdout + out += awk_out + apps += out.splitlines() + # Procesar aplicaciones Flatpak. + pkgdir = f'{mntdir}/var/lib/flatpak' + files = glob.glob (f'{pkgdir}/app/*/current/active/deploy/*') + for f in files: + p = open (f.strip()).read().split ('\0') + try: + if (p[0] != 'flathub'): raise ValueError + apps.append ('{} (flatpak) {}'.format (p[p.index('appdata-name') + 4], p[p.index('appdata-version') + 1])) + except ValueError: + pass + + elif 'Windows' == ostype: + if shutil.which ('hivexregedit'): + hive = RegistryLib.ogGetHivePath (mntdir, 'software') + if hive: + cmd1_out = subprocess.run (['hivexregedit', '--unsafe-printable-strings', '--export', hive, r'\Microsoft\Windows\CurrentVersion\Uninstall'], capture_output=True, text=True).stdout + cmd1_out += subprocess.run (['hivexregedit', '--unsafe-printable-strings', '--export', hive, r'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'], capture_output=True, text=True).stdout + out = name = '' + for l in cmd1_out.splitlines(): + words = l.split ('"') + if len(words) < 4: continue + if (re.match (r'\[', words[0])): name='' + if (re.search ('DisplayName', words[1])): name=words[3] + if (re.search ('DisplayVersion', words[1])): apps.append (f'{name} {words[3]}') + else: + keys = RegistryLib.ogListRegistryKeys (mntdir, 'software', r'\Microsoft\Windows\CurrentVersion\Uninstall') + keys32 = RegistryLib.ogListRegistryKeys (mntdir, 'software', r'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall') + for k in keys: + prog = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayName') + if prog: + vers = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayVersion') + apps.append (f'{prog} {vers}') + for k in keys32: + prog = RegistryLib.gGetRegistryValue (mntdir, 'software', rf'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayName') + if prog: + vers = RegistryLib.ogGetRegistryValue (mntdir, 'software', rf'\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{k}\DisplayVersion') + apps.append (f'{prog} {vers}') + + elif 'MacOS' == ostype: + files = subprocess.run (['find', f'{mntdir}/Applications', '-type', 'd', '-name', '*.app', '-prune', '-print'], capture_output=True, text=True).stdout.splitlines() + for k in files: + FILE = f'{k}/Contents/version.plist' + if not os.stat (FILE).st_size: + FILE = f'{k}/Contents/version.plist.uncompress' + if os.stat (FILE).st_size: + VERSION = subprocess.run (['awk', '-F[<>]', '/ShortVersionString/ {getline;v=$3} END {print v}', FILE], capture_output=True, text=True).stdout.strip() + bn = os.path.basename (k) + bn = re.sub ('.app$', '', bn) + apps.append (f'{bn} {VERSION}') + + elif 'BSD' == ostype: + sqlite_out = subprocess.run (['sqlite3', f'{mntdir}/var/db/pkg/local.sqlite'], input='SELECT name FROM pkg_search;\n', capture_output=True, text=True).stdout + for l in sqlite_out.splitlines(): + apps.append (' '.join (re.search ('(.*)-(.*)', l).groups())) + + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTOS, f'{disk}, {par} ({ostype})') + return None + + os_version = ogGetOsVersion (disk, par).split (':')[1] + return [os_version] + sorted (set (apps)) + +## https://stackoverflow.com/questions/2522651/find-a-key-inside-a-deeply-nested-dictionary/2522706#2522706 +def _find_key_recursive(plist_dict, key_substr): + for k in plist_dict.keys(): + if key_substr in k: return plist_dict[k] + for k, v in plist_dict.items(): + if type(v) is dict: # Only recurse if we hit a dict value + value = _find_key_recursive(v, key_substr) + if value: + return value + return '' + +#/** +# ogGetOsVersion int_ndisk int_nfilesys +#@brief Devuelve la versión del sistema operativo instalado en un sistema de archivos. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden de la partición +#@return OSType:OSVersion - tipo y versión del sistema operativo. +#@note OSType = { Android, BSD, GrubLoader, Hurd, Linux, MacOS, Solaris, Windows, WinLoader } +#@note Requisitos: awk, head, chroot +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o partición no corresponden con un dispositiv +#@exception OG_ERR_PARTITION Fallo al montar el sistema de archivos. +#*/ ## +#ogGetOsVersion ("1", "2") => "Linux:Ubuntu precise (12.04 LTS) 64 bits" +def ogGetOsVersion(disk, part): + mntdir = FileSystemLib.ogMount (disk, part) + if not mntdir: + return None + + type = version = None + is64bit = '' + +# Buscar tipo de sistema operativo. +# Para GNU/Linux: leer descripción. + os_release = os.path.join(mntdir, "etc/os-release") + if os.path.isfile(os_release): + type = 'Linux' + with open(os_release, "r") as f: + for line in f: + if line.startswith("PRETTY_NAME"): + version = line.split("=", 1)[1].strip().strip('"') + break + + if not version: + lsb_release = os.path.join(mntdir, "etc/lsb-release") + if os.path.isfile(lsb_release): + type = 'Linux' + with open(lsb_release, "r") as f: + for line in f: + if line.startswith("DISTRIB_DESCRIPTION"): + version = line.split("=", 1)[1].strip().strip('"') + break + + if not version: + for distrib in ["redhat", "SuSE", "mandrake", "gentoo"]: + distrib_file = os.path.join(mntdir, f"etc/{distrib}-release") + if os.path.isfile(distrib_file): + type = 'Linux' + with open(distrib_file, "r") as f: + version = f.readline().strip() + break + + if not version: + arch_release_file = os.path.join(mntdir, "etc/arch-release") + if os.path.isfile(arch_release_file): + type = 'Linux' + version = "Arch Linux" + + if not version: + slack_release_file = os.path.join(mntdir, "slackware-version") + if os.path.isfile(slack_release_file): + type = 'Linux' + with open (slack_release_file, 'r') as fd: + c = fd.read() + version = "Slackware {c}" + +# Si no se encuentra, intentar ejecutar "lsb_release". + if not version: + out = subprocess.run (['chroot', mntdir, 'lsb_release', '-d'], capture_output=True, text=True).stdout + m = re.search (':\t(.*)', out) + if m: + type = 'Linux' + version = m.group(1) +# Comprobar Linux de 64 bits. + if version and os.path.exists(os.path.join(mntdir, "lib64")): + is64bit = ogGlobals.lang.MSG_64BIT +# Para Android, leer fichero de propiedades. + if not version: + type = 'Android' + files = glob.glob (os.path.join (mntdir, 'android*/system/build.prop')) + if files and os.path.isfile (files[0]): + v = [] + with open (files[0], 'r') as f: + for line in f: + if 'product.brand' in line or 'build.version.release' in line: + v.append (line.split('=')[1].strip()) + version = ' '.join (v) + if os.path.exists(os.path.join(mntdir, "lib64")): + is64bit = ogGlobals.lang.MSG_64BIT +# Para GNU/Hurd, comprobar fichero de inicio (basado en os-prober). + if not version: + type = 'Hurd' + if os.path.exists(os.path.join(mntdir, "hurd/init")): + version = 'GNU/Hurd' +# Para Windows: leer la version del registro. + if not version: + type = 'Windows' + build = 0 + file = RegistryLib.ogGetHivePath (mntdir, 'SOFTWARE') + if file: + # Nuevo método más rápido para acceder al registro de Windows.. + i = '\n'.join ([ + f'load {file}', + r'cd \Microsoft\Windows NT\CurrentVersion', + 'lsval ProductName', + 'lsval DisplayVersion', + ]) + version = subprocess.run (['hivexsh'], input=i, capture_output=True, text=True).stdout + version = version.replace ('\n', ' ') +# Recoge el valor del número de compilación para ver si es Windows 10/11 + i = '\n'.join ([ + f'load {file}', + r'cd \Microsoft\Windows NT\CurrentVersion', + 'lsval CurrentBuildNumber', + ]) + build = subprocess.run (['hivexsh'], input=i, capture_output=True, text=True).stdout + + if subprocess.run (['reglookup', '-H', '-p', 'Microsoft/Windows/CurrentVersion/ProgramW6432Dir', file], capture_output=True, text=True).stdout: + is64bit = ogGlobals.lang.MSG_64BIT + + if not version: + # Compatibilidad con métrodo antiguo y más lento de acceder al registro. + version = RegistryLib.ogGetRegistryValue (mntdir, 'software', r'\Microsoft\Windows NT\CurrentVersion\ProductName') + if RegistryLib.ogGetRegistryValue (mntdir, 'software', r'\Microsoft\Windows\CurrentVersion\ProgramW6432Dir'): + is64bit = ogGlobals.lang.MSG_64BIT + # Si la compilación es mayor o igual a 22000 es Windows 11 + if int (build) >= 22000: + version = version.replace ('10', '11') +# Para cargador Windows: buscar versión en fichero BCD (basado en os-prober). + if not version: + type = 'WinLoader' + file = FileLib.ogGetPath (file=f'{mntdir}/boot/bcd') + if not file: + file = FileLib.ogGetPath (file=f'{mntdir}/EFI/Microsoft/boot/bcd') + if file: + for distrib in 'Windows Recovery', 'Windows Boot': + with open (file, 'rb') as fd: + contents = fd.read() + distrib_utf16_regex = re.sub (r'(.)', '\\1.', distrib) + distrib_utf16_regex = bytes (distrib_utf16_regex, 'ascii') + if re.search (distrib_utf16_regex, contents): + version = f'{distrib} loader' +# Para macOS: detectar kernel y completar con fichero plist de información del sistema. + if not version: + type = 'MacOS' + # Kernel de Mac OS (no debe ser fichero de texto). + file = f'{mntdir}/mach_kernel' + out = subprocess.run (['file', '--brief', file], capture_output=True, text=True).stdout + if not 'text' in out: + # Obtener tipo de kernel. + if 'Mach-O' in out: version = 'macOS' + if 'Mach-O 64-bit' in out: is64bit = ogGlobals.lang.MSG_64BIT + # Datos de configuración de versión de Mac OS. + file = f'{mntdir}/System/Library/CoreServices/SystemVersion.plist' + if os.path.exists (file): + with open (file, 'rb') as fd: + contents = fd.read() + plist_dict = plistlib.loads (contents) + n = _find_key_recursive (plist_dict, 'ProductName') + v = _find_key_recursive (plist_dict, 'ProductVersion') + version = f'{n} {v}'.strip() + # Datos de recuperación de macOS. + if version and os.path.exists (f'{mntdir}/com.apple.recovery.boot'): + version += ' recovery' + +# Para FreeBSD: obtener datos del Kernel. +### TODO Revisar solución. + if not version: + type = 'BSD' + file = f'{mntdir}/boot/kernel/kernel' + if os.path.exists (file): + lines = subprocess.run (['strings', file], capture_output=True, text=True).stdout.splitlines() + release_search = list (filter (lambda x: re.search ('@.*RELEASE', x), lines)) + if release_search: + first, second, *rest = release_search[0].split() + first = first.replace ('@(#)', '') + version = f'{first} {second}' + out = subprocess.run (['file', '--brief', file], capture_output=True, text=True).stdout + if 'x86-64' in out: is64bit = ogGlobals.lang.MSG_64BIT +# Para Solaris: leer el fichero de versión. +### TODO Revisar solución. + if not version: + type = 'Solaris' + file = f'{mntdir}/etc/release' + if os.path.exists (file): + with open (file, 'r') as fd: + version = fd.readline().strip +# Para cargador GRUB, comprobar fichero de configuración. + if not version: + type = 'GrubLoader' + for file in f'{mntdir}/grub/menu.lst', f'{mntdir}/boot/grub/menu.lst': + if os.path.exists (file): + VERSION = 'GRUB Loader' + for entry in f'{mntdir}/grub/grub.cfg', f'{mntdir}/grub2/grub.cfg', f'{mntdir}/EFI/*/grub.cfg', f'{mntdir}/boot/grub/grub.cfg', f'{mntdir}/boot/grub2/grub.cfg', f'{mntdir}/boot/EFI/*/grub.cfg': + for file in glob.glob (entry): + if os.path.exists (file): + version = 'GRUB2 Loader' + + + + + +# Mostrar resultado y salir sin errores. + if version: return f"{type}:{version} {is64bit}" + return None diff --git a/client/lib/python3/NetLib.py b/client/lib/python3/NetLib.py new file mode 100644 index 0000000..e36f863 --- /dev/null +++ b/client/lib/python3/NetLib.py @@ -0,0 +1,315 @@ +#/** +#@file NetLib.py +#@brief Librería o clase Net +#@class Net +#@brief Funciones básicas de red. +#@warning License: GNU GPLv3+ +#*/ + +import subprocess +import sys +import os +import json +import re + +import ogGlobals +import SystemLib +import FileLib + +def _ogConnect_options(): + ## the original bash code does: eval $(grep "OPTIONS=" /scripts/ogfunctions) + ## this is highly insecure but we need to keep it for now + opt = subprocess.run (['grep', '-o', 'OPTIONS=.*', '/scripts/ogfunctions'], capture_output=True, text=True).stdout.strip() + exec (opt, globals()) + return OPTIONS + +## defined in /scripts/ogfunctions. We can't tackle that yet. +## this is a quick implementation just to unblock development +def _ogConnect (server, protocol, src, dst, options, readonly): + if 'smb' != protocol: return None ## only supported value right now + write_option = ',ro' if readonly else ',rw' + options += write_option + return not subprocess.run (['mount.cifs', f'//{server}/{src}', dst] + options.split()).returncode + + +#/** +# ogChangeRepo IPREPO [ OgUnit ] +#@brief Cambia el repositorio para el recurso remoto images. +#@param 1 Ip Repositorio +#@param 2 Abreviatura Unidad Organizativa +#@return Cambio recurso remoto en OGIMG. +#*/ +def ogChangeRepo(ip_repo, og_unit=None): + ogprotocol = os.environ['ogprotocol'] or 'smb' + + if og_unit: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_GENERIC, 'the og_unit parameter became unsupported') + return None + + try: + mount = subprocess.run (['mount'], capture_output=True, text=True).stdout + ro = bool (list (filter (lambda line: re.search (r'ogimages.*\bro,', line), mount.splitlines()))) + + current_repo = ogGetRepoIp() + new_repo = current_repo if ip_repo.upper() == "REPO" else ip_repo + if new_repo == current_repo: return True + + subprocess.run(["umount", ogGlobals.OGIMG], check=True) + + SystemLib.ogEcho (['session', 'log'], None, f'{ogGlobals.lang.MSG_HELP_ogChangeRepo} {new_repo}') + options = _ogConnect_options() + if not _ogConnect (new_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro): + _ogConnect (current_repo, ogprotocol, 'ogimages', ogGlobals.OGIMG, options, ro) + SystemLib.ogRaiseError( + "session", + ogGlobals.OG_ERR_REPO, + f"Error connecting to the new repository: {new_repo}", + ) + return False + + SystemLib.ogEcho( + ["session", "log"], + None, + f"Repository successfully changed to {new_repo}".strip(), + ) + + return True + + except Exception as e: + SystemLib.ogRaiseError( + "session", + ogGlobals.OG_ERR_GENERIC, + f"Error executing ogChangeRepo: {e}", + ) + return None + +#/** +# ogGetGroupDir [ str_repo ] +#@brief Devuelve el camino del directorio para el grupo del cliente. +#@param str_repo repositorio de imágenes (opcional) +#@return path_dir - Camino al directorio del grupo. +#@note repo = { REPO, CACHE } REPO por defecto +#@exception OG_ERR_FORMAT formato incorrecto. +#*/ +def ogGetGroupDir(repo=None): + try: + repo = repo or "REPO" + + group = ogGetGroupName() + if group: + dir_path = FileLib.ogGetPath(repo, f"/groups/{group}") + if dir_path and os.path.isdir(dir_path): + return dir_path + + return None + + except Exception as e: + SystemLib.ogRaiseError( + "session", + ogGlobals.OG_ERR_FORMAT, + f"Error in ogGetGroupDir: {e}" + ) + return None + +#/** +# ogGetGroupName +#@brief Devuelve el nombre del grupo al que pertenece el cliente. +#@return str_group - Nombre de grupo. +#*/ +def ogGetGroupName(): + try: + group = globals().get("group", None) + return group if group else None + except Exception as e: + print(f"Error in ogGetGroupName: {e}") + return None + +#/** +# ogGetHostname +#@brief Muestra el nombre del cliente. +#@return str_host - nombre de máquina +#*/ ## +def ogGetHostname(): +# Tomar nombre de la variable HOSTNAME + host = os.getenv("HOSTNAME", "").strip() + if host: return host + +# Si no, tomar del DHCP, opción host-name /* (comentario para Doxygen) + dhcp_file = "/var/lib/dhcp3/dhclient.leases" + if os.path.exists(dhcp_file): + with open(dhcp_file, "r") as f: + for line in f: + if 'option host-name' in line: + return line.split('"')[1].strip(";") + +# Si no, leer el parámetro del kernel hostname (comentario para Doxygen) */ + cmdline_file = "/proc/cmdline" + if os.path.exists(cmdline_file): + with open(cmdline_file, "r") as f: + for entry in f.read().split(): + if entry.startswith("hostname="): + return entry.split("=")[1].strip() + + +#/** +# ogGetIpAddress +#@brief Muestra la dirección IP del sistema +#@return str_ip - Dirección IP +#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf +#*/ ## +def ogGetIpAddress(): + if "IPV4ADDR" in os.environ: + ip = os.environ["IPV4ADDR"] + if '/' in ip: ip = ip.split ('/')[0] + return ip + + extra_args = [] + if "DEVICE" in os.environ: + extra_args = [ "dev", os.environ["DEVICE"] ] + ipas = subprocess.run (['ip', '-json', 'address', 'show', 'up'] + extra_args, capture_output=True, text=True).stdout + + ipasj = json.loads (ipas) + addresses = [] + for e in ipasj: + if 'lo' == e['ifname']: continue + if 'addr_info' not in e: continue + addrs = e['addr_info'] + for a in addrs: + if 'inet' != a['family']: continue + addresses.append ({ 'local': a['local'], 'prefixlen': a['prefixlen'] }) + + if 1 != len (addresses): + raise Exception ('more than one local IP address found') + return addresses[0] + + +#/** +# ogGetMacAddress +#@brief Muestra la dirección Ethernet del cliente. +#@return str_ether - Dirección Ethernet +#*/ ## +def ogGetMacAddress(): + try: + if "DEVICE" in os.environ: + device = os.environ["DEVICE"] + result = subprocess.run( + ["ip", "-o", "link", "show", "up", "dev", device], + capture_output=True, + text=True, + check=True + ).stdout + else: + result = subprocess.run( + ["ip", "-o", "link", "show", "up"], + capture_output=True, + text=True, + check=True + ).stdout + + mac_addresses = [] + for line in result.splitlines(): + if "link/ether" in line: + parts = line.split() + for i, part in enumerate(parts): + if part == "link/ether": + mac_addresses.append(parts[i + 1].upper()) + + if mac_addresses: + print (f'nati: ogGetMacAddress: {mac_addresses[0]}') + return mac_addresses[0] + else: + print("No active mac address found") + return None + + except subprocess.CalledProcessError as e: + print(f"Error executing ip command: {e.stderr}") + return None + except Exception as e: + print(f"Unexpected error: {str(e)}") + return None + +#/** +# ogGetNetInterface +#@brief Muestra la interfaz de red del sistema +#@return str_interface - interfaz de red +#@note Usa las variables utilizadas por el initrd "/etc/net-ethX.conf +#*/ ## +def ogGetNetInterface(): + if len(sys.argv) >= 2 and sys.argv[1] == "help": + SystemLib.ogHelp("ogGetNetInterface", "ogGetNetInterface", "ogGetNetInterface => eth0") + return + + if "DEVICE" in os.environ: + print(os.environ["DEVICE"]) + + return 0 + +#/** +# ogGetRepoIp +#@brief Muestra la dirección IP del repositorio de datos. +#@return str_ip - Dirección IP +#*/ ## +def ogGetRepoIp(): + out = subprocess.run (["findmnt", "--json", "--output", "SOURCE,FSTYPE", ogGlobals.OGIMG], capture_output=True, text=True).stdout + try: + j = json.loads (out) + except json.decoder.JSONDecodeError: + return None + + if 'filesystems' not in j: return None + source = j['filesystems'][0]['source'] + fstype = j['filesystems'][0]['fstype'] + + if 'nfs' == fstype: return source.split(":")[0] + elif 'cifs' == fstype: return source.split("/")[2] + + return None + +#/** +# ogGetServerIp +#@brief Muestra la dirección IP del Servidor de OpenGnSys. +#@return str_ip - Dirección IP +#@note Comprobacion segun protocolo de conexion al Repo +#*/ ## +def ogGetServerIp(): + return os.environ['ogcore'] + +#/** +# ogGetServerPort +#@brief Muestra el puerto del Servidor de OpenGnSys. +#@return str_port - Puerto +#*/ ## +def ogGetServerPort(): + if 'ogcore_port' in os.environ: + return os.environ['ogcore_port'] + else: + return '8443' + + +#/** +# ogMakeGroupDir [ str_repo ] +#@brief Crea el directorio para el grupo del cliente. +#@param str_repo repositorio de imágenes (opcional) +#@return (nada) +#@note repo = { REPO, CACHE } REPO por defecto +#@exception OG_ERR_FORMAT formato incorrecto. +#*/ +def ogMakeGroupDir(): + REPO = "" + DIR = "" + GROUP = "" + + if len(sys.argv) < 2: + SystemLib.ogHelp("ogMakeGroupDir", "ogMakeGroupDir str_repo", "ogMakeGroupDir", "ogMakeGroupDir REPO") + return + + if len(sys.argv) == 1: + REPO = "REPO" + else: + REPO = sys.argv[1] + + DIR = FileLib.ogGetPath(REPO, "/groups/" + ogGetGroupName(), stderr=subprocess.DEVNULL) + if DIR: + subprocess.run(["mkdir", "-p", DIR], stderr=subprocess.DEVNULL) + + return 0 diff --git a/client/lib/python3/PostConfLib.py b/client/lib/python3/PostConfLib.py new file mode 100644 index 0000000..e97b266 --- /dev/null +++ b/client/lib/python3/PostConfLib.py @@ -0,0 +1,320 @@ +#/** +#@file PostConfLib.py +#@brief Librería o clase PostConf +#@class PostConf +#@brief Funciones para la postconfiguración de sistemas operativos. +#@warning License: GNU GPLv3+ +#*/ + +import os +import glob +import subprocess + +import ogGlobals +import SystemLib +import FileSystemLib +import FileLib +import NetLib +import RegistryLib +import InventoryLib +import BootLib + +#/** +# ogCleanOs int_ndisk int_nfilesys +#@brief Elimina los archivos que no son necesarios en el sistema operativo. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Partición desconocida o no accesible. +#@note Antes incluido en la funcion ogReduceFs +#@return (nada) +#*/ ## +#ogCleanOs (1, 1) +def ogCleanOs (disk, par): + t = InventoryLib.ogGetOsType (disk, par) + if 'Linux' == t: + BootLib.ogCleanLinuxDevices (disk, par) + mntdir = FileSystemLib.ogMount (disk, par) + for t in glob.glob ('{mntdir}/tmp/*'): + shutil.rmtree (t) + elif 'Windows' == t: + for f in 'pagefile.sys', 'hiberfil.sys', 'swapfile.sys': + p = FileLib.ogGetPath (src=f'{disk} {par}', file=f) + if p: FileLib.ogDeleteFile (disk=disk, par=par, file=f) + + + +#/** +# ogInstallMiniSetup int_ndisk int_npartition str_filename [str_admuser str_admpassword bool_autologin [str_autouser str_autopassword] ] +#@brief Metafunción para instalar archivo que se ejecutará en el arranque de Windows. +#@see ogInstallFirstBoot ogInstallRunonce +#*/ ## +def ogInstallMiniSetup (disk, par, cmdfile, user=None, pwd=None, autologin=False, userauto=None, pwdauto=None): + if user: + ogInstallRunonce (disk, par, cmdfile, user, pwd, autologin, userauto, pwdauto) + else: + ogInstallFirstBoot (disk, par, cmdfile) + + +#/** +# ogInstallFirstBoot int_ndisk int_npartition str_filename +#@brief Crea unas claves del registro y el archivo cmd que se ejecutara en el primer arranque estando la maquina en un estado bloqueado +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@param str_filename nombre del archivo .cmd a ejecutar en el arranque +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@note El archivo estará en system32 y será visible por el sistema. +#*/ ## +#ogInstallFirstBoot ('1', '1', 'filename.cmd') +def ogInstallFirstBoot (disk, par, cmdfile): + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: return + for i in ['winnt', 'windows']: + dir = FileLib.ogGetPath (file=f'{mntdir}/{i}/system32') + if dir: cmddir = dir + if not cmddir: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mntdir}/windows/system32') + return + full_cmdfile = f'{cmddir}/{cmdfile}' + bn = os.path.basename (full_cmdfile) + + # Creamos el archivo cmd y creamos un par de comandos para que una vez acabe la + # postconfiguracion resetee el mini setup, sino lo haria en cada arranque. + with open (full_cmdfile, 'w') as fd: + fd.write (r'REG ADD HKLM\System\Setup /v SystemSetupInProgress /t REG_DWORD /d 0 /f' + '\n') + fd.write (r'REG ADD HKLM\System\Setup /v CmdLine /t REG_SZ /d "" /f' + '\n') + + # Crear los valores de registro necesarios para que se haga la ejecución del .cmd al aranque. + RegistryLib.ogSetRegistryValue (mntdir, 'SYSTEM', r'\Setup\SystemSetupInProgress', 1) + RegistryLib.ogSetRegistryValue (mntdir, 'SYSTEM', r'\Setup\SetupType', 4) + #RegistryLib.ogDeleteRegistryValue (mntdir, 'SYSTEM', r'\Setup\CmdLine') + RegistryLib.ogAddRegistryValue (mntdir, 'SYSTEM', r'\Setup\CmdLine') + RegistryLib.ogSetRegistryValue (mntdir, 'SYSTEM', r'\Setup\CmdLine', f'cmd.exe /c {bn}') + + +#/** +# ogInstallRunonce int_ndisk int_npartition str_filename str_adm_user str_adm_password bool_autologin [str_auto_user str_auto_password] +#@brief Crea el archivo cmd que se ejecutara en el runonce de un usuario administrador +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@param str_filename nombre del archivo .cmd a ejecutar en el arranque (estara en system32 y sera visible por el sistema) +#@param str_adm_user usuario administrador para hacer autologin y ejecutar el runonce +#@param str_adm_password password del usuario administrador +#@param bool_autologin si despues de la postconfiguracion queremos que la maquina haga autologin (0 o 1) +#@param str_auto_user Usuario con el que queremos que haga autologin despues de la postconfiguracion +#@param str_auto_password Password del usuario que hara autologin +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#*/ ## +#ogInstallRunonce ('1', '1', 'filename.cmd', 'administrator', 'passadmin', '1', 'userauto', 'pwdauto') +#ogInstallRunonce ('1', '1', 'filename.cmd', 'administrator', 'passadmin', '0') +def ogInstallRunonce (disk, par, cmdfile, user, pwd, autologin, userauto=None, pwdauto=None): + mountpoint = FileLib.ogGetPath (src=f'{disk} {par}', file='/') + for i in ['winnt', 'windows']: + dir = FileLib.ogGetPath (file=f'{mountpoint}/{i}/system32') + if dir: cmddir = dir + if not cmddir: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mountpoint}/Windows/System32') + return + full_cmdfile = f'{cmddir}/{cmdfile}' + if not autologin: + # Si no queremos hacer autologin despues de la postconfiguracion lo indicamos en las claves de registro + with open (full_cmdfile, 'w') as fd: + fd.write (r'DEL C:\ogboot.*' + '\n') + fd.write (r'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon /t REG_SZ /d 0 /f' + '\n') + fd.write (r'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /t REG_SZ /d "" /f' + '\n') + fd.write (r'REG DELETE "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /f' + '\n') + else: + # Si queremos hacer autologin despues de la postconfiguracion introducimos la informacion en las claves de registro + with open (full_cmdfile, 'w') as fd: + fd.write (r'DEL C:\ogboot.*' + '\n') + fd.write (r'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon /t REG_SZ /d 1 /f' + '\n') + fd.write (fr'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /t REG_SZ /d "{userauto}" /f' + '\n') + fd.write (fr'REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /t REG_SZ /d "{pwdauto}" /f' + '\n') + #Creamos las claves de registro necesarias para que meter el cmd en el runonce del usuario y este haga autologin + RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows\CurrentVersion\RunOnce\PostConfiguracion') + RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows\CurrentVersion\RunOnce\PostConfiguracion', rf'C:\windows\system32\{cmdfile}') + RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon') + RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoAdminLogon', 1) + RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName') + RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName', user) + RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultDomainName') + RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultDomainName', '.\\') + RegistryLib.ogAddRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultPassword') + RegistryLib.ogSetRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultPassword', pwd) + RegistryLib.ogDeleteRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\ForceAutoLockOnLogon') + RegistryLib.ogDeleteRegistryValue (mountpoint, 'software', r'\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoLogonCount') + +#/** +# ogAddCmd int_ndisk int_npartition str_filename str_commands +#@brief Añade comandos al cmd creado por ogInstalMiniSetup +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@param str_filename nombre del fichero cmd (siempre se guardara en windows\system32\para que sea visible por el sistema +#@param str_commands comando o comandos que se añadiran al fichero +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#*/ ## +#ogAddCmd ('1', '1', 'filename.cmd', 'command') +def ogAddCmd (disk, par, cmdfile, cmd): + mountpoint = FileSystemLib.ogMount (disk, par) + if not mountpoint: return + + full_cmdfile = FileLib.ogGetPath (file=f'{mountpoint}/windows/system32') + '/' + cmdfile + if not full_cmdfile: + ogInstallMiniSetup (disk, par, cmdfile) + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mountpoint}/windows/system32/{cmdfile}') + return + + # Concatenamos el comando en el fichero de comandos + with open (full_cmdfile, 'a') as fd: + fd.write (cmd + '\n') + + +#/** +# ogDomainScript int_ndisk int_npartition str_domain str_user str_password +#@brief Crea un script .vbs para unir al dominio una maquina windows y el comando adequado en el archivo cmd creado por ogInstallMiniSetup +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@param str_filename nombre del fichero cmd donde deberemos introducir el comando de ejecutar el script vbs +#@param str_domain dominio donde se quiere conectar +#@param str_user usuario con privilegios para unir al dominio +#@param str_password password del usuario con privilegios +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#*/ ## + + +### PRUEBAS. + +#/** +# ogConfigureOgagent int_ndisk int_filesys +#@brief Modifica el fichero de configuración del nuevo agente OGAent para sistemas operativos. +#@param int_ndisk nº de orden del disco +#@param int_filesys nº de orden del sistema de archivos +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero o dispositivo no encontrado. +#@exception OG_ERR_LOCKED Sistema de archivos bloqueado. +#*/ ## +def ogConfigureOgagent (disk, par): + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: + return + + for agentdir in ['usr/share/OGAgent', 'Program Files/OGAgent', 'Program Files (x86)/OGAgent', 'Applications/OGAgent.app']: + cfgfile = FileLib.ogGetPath (file=f'{mntdir}/{agentdir}/cfg/ogagent.cfg') + if cfgfile: break + + if not cfgfile: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, 'ogagent.cfg') + return + + ogcore_scheme = 'https' + ogcore_ip = NetLib.ogGetServerIp() + ogcore_port = NetLib.ogGetServerPort() + cfgfile_patched = cfgfile + '.patched' + in_opengnsys_section = False + with open (cfgfile, 'r') as fdin: + with open (cfgfile_patched, 'w') as fdout: + while True: + lineout = linein = fdin.readline() + if not linein: break + if in_opengnsys_section: + if 'remote' == linein[0:6]: + lineout = f'remote={ogcore_scheme}://{ogcore_ip}:{ogcore_port}/opengnsys/rest/\n' + if '[' == linein[0:1]: + in_opengnsys_section = False + if '[opengnsys]' == linein[0:11]: + in_opengnsys_section = True + fdout.write (lineout) + os.rename (cfgfile_patched, cfgfile) + + +#/** +# ogInstallLaunchDaemon int_ndisk int_nfilesys str_filename +#@brief Instala archivo que se ejecutará en el arranque de macOS. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@param str_filename nombre del script +#return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero o directorio no encontrado. +#@npte Crea ficheros de configuración /Library/LaunchDaemon/es.opengnsys.Script.plist. +#*/ ## + + +### PRUEBAS. + +#/** +# ogAddToLaunchDaemon int_ndisk int_nfilesys str_filename str_commands +#@brief Añade comandos al script creado por ogInstalLaunchDaemon. +#@param int_ndisk nº de orden del disco +#@param int_nfilesys nº de orden del sistema de archivos +#@param str_filename nombre del script (siempre se guardará en /usr/share para que sea visible por el sistema +#@param str_commands comando o comandos que se añadiran al fichero +#return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero o directorio no encontrado. +#*/ ## + + +#/** +# ogUninstallLinuxClient int_ndisk int_filesys +#@brief Desinstala el cliente OpenGnSys para sistemas operativos GNU/Linux. +#@param int_ndisk nº de orden del disco +#@param int_filesys nº de orden del sistema de archivos +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Paritición o sistema de archivos incorrectos. +#@exception OG_ERR_LOCKED Sistema de archivos bloqueado. +#*/ ## +def ogUninstallLinuxClient (disk, par): + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: + return + + for f in [ + f'{mntdir}/usr/sbin/ogAdmLnxClient', + f'{mntdir}/sbin/ogAdmLnxClient', + f'{mntdir}/usr/local/sbin/ogAdmLnxClient', + f'{mntdir}/etc/ogAdmLnxClient.cfg', + f'{mntdir}/usr/local/etc/ogAdmLnxClient.cfg', + ]: + try: os.remove (f) + except: pass + + for f in [ + f'{mntdir}/etc/rc.local', + f'{mntdir}/etc/rc.d/rc.local', + f'{mntdir}/usr/local/etc/rc.local', + f'{mntdir}/usr/local/etc/rc.d/rc.local', + ]: + subprocess.run (['sed', '-i', '-e', '/ogAdmLnxClient/ d', f], stderr=subprocess.DEVNULL) + + +#/** +# ogUninstallWindowsClient int_ndisk int_filesys str_filename +#@brief Desinstala el cliente OpenGnSys para sistemas operativos Windows. +#@param int_ndisk nº de orden del disco +#@param int_npartition nº de orden de la partición +#@param str_filename nombre del fichero cmd donde deberemos introducir el comando de ejecutar el script vbs +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_PARTITION Paritición o sistema de archivos incorrectos. +#@exception OG_ERR_LOCKED Sistema de archivos bloqueado. +#*/ ## +#ogUninstallWindowsClient ('1', '1', 'filename.cmd') +def ogUninstallWindowsClient (disk, par, cmdfile): + mntdir = FileSystemLib.ogMount (disk, par) + if not mntdir: return + + exe1 = FileLib.ogGetPath (file=f'{mntdir}/windows/ogAdmWinClient.exe') + exe2 = FileLib.ogGetPath (file=f'{mntdir}/winnt/ogAdmWinClient.exe') + if exe1 or exe2: + ogAddCmd (disk, par, cmdfile, 'ogAdmWinClient -remove') + ogAddCmd (disk, par, cmdfile, r'DEL C:\Windows\ogAdmWinClient.exe') + ogAddCmd (disk, par, cmdfile, r'DEL C:\Winnt\ogAdmWinClient.exe') diff --git a/client/lib/python3/ProtocolLib.py b/client/lib/python3/ProtocolLib.py new file mode 100644 index 0000000..18c8bb8 --- /dev/null +++ b/client/lib/python3/ProtocolLib.py @@ -0,0 +1,973 @@ +#!/usr/bin/python3 + +import subprocess +import re +import json +import os.path +import shutil + +import ogGlobals +import SystemLib +import ImageLib +import FileSystemLib +import StringLib +import NetLib +import DiskLib +import FileLib +import CacheLib + +#/** +#@file ProtocolLib.py +#@brief Librería o clase Protocol +#@class Protocol +#@brief Funciones para transmisión de datos +#@warning License: GNU GPLv3+ +#*/ + + +##################### FUNCIONES UNICAST ################ + +#/** +# ogUcastSyntax +#@brief Función para generar la instrucción de transferencia de datos unicast +#@param 1 Tipo de operación [ SENDPARTITION RECEIVERPARTITION SENDFILE RECEIVERFILE ] +#@param 2 Sesion Unicast +#@param 3 Dispositivo (opción PARTITION) o fichero(opción FILE) que será enviado. +#@param 4 Tools de clonación (opcion PARTITION) +#@param 5 Tools de compresion (opcion PARTITION) +#@return instrucción para ser ejecutada. +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_UCASTSYNTAXT formato de la sesion unicast incorrecta. +#@note Requisitos: mbuffer +#@todo: controlar que mbuffer esta disponible para los clientes. +#*/ ## + +#ogUcastSyntax SENDPARTITION 8000:172.17.36.11:172.17.36.12 device tool level +#ogUcastSyntax RECEIVERPARTITION 8000:172.17.36.249 device tool level + +#ogUcastSyntax SENDFILE 8000:172.17.36.11:172.17.36.12 file +#ogUcastSyntax RECEIVERFILE 8000:172.17.36.249 file + +def ogUcastSyntax (op, sess, file=None, device=None, tool=None, level=None): + if 'SENDPARTITION' == op or 'RECEIVERPARTITION' == op: + if device is None: + raise TypeError ('missing required argument: "device"') + if tool is None: + raise TypeError ('missing required argument: "tool"') + if tool.lower() not in ['partclone', 'partimage', 'ntfsclone']: + raise TypeError (f'argument "tool" has unsupported value "{tool}"') + if level is None: + raise TypeError ('missing required argument: "level"') + if level.lower() not in ['lzop', 'gzip', '0', '1']: + raise TypeError (f'argument "level" has unsupported value "{level}"') + elif 'SENDFILE' == op or 'RECEIVERFILE' == op: + if file is None: + raise TypeError ('missing required argument: "file"') + else: + raise TypeError ('first parameter should match (SEND|RECEIVER)(PARTITION|FILE), eg. "SENDFILE"') + + if 'SEND' in op: mode = 'server' + else: mode = 'client' + + session = sess.split (':') + + portbase = int (session[0]) + if portbase not in range (8000, 8006): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession portbase {portbase}') ## || PERROR=3 + return + + if 'server' == mode: + address = '' + for i in range (1, len (session)): + address += f' -O {session[i]}:{portbase}' + else: + address = f'{session[1]}:{portbase}' + #print (f'nati mode ({mode}) address ({address})') + + if 'SENDPARTITION' == op: + syn = ImageLib.ogCreateImageSyntax (device, ' ', tool, level) + ## REQUIRES package mbuffer to be installed!! + ## otherwise, param2 in ImageLib.ogCreateImageSyntax() is not '| mbuffer' but empty + ## and then parts[2] is out of range + parts = syn.split ('|') + #print (f'nati syn ({syn}) parts ({parts})') + prog1 = f'{parts[0]}|{parts[2]}'.strip() + prog1 = prog1.replace ('>', '').strip() + return f'{prog1} | mbuffer {address}' + elif 'RECEIVERPARTITION' == op: + syn = ImageLib.ogRestoreImageSyntax (' ', device, tool, level) + parts = syn.split ('|') + compressor = parts[0].strip() + tools = parts[-1].strip() + return f'mbuffer -I {address} | {compressor} | {tools}' + elif 'SENDFILE' == op: + return f'mbuffer {address} -i {file}' + elif 'RECEIVERFILE' == op: + return f'mbuffer -I {address} -i {file}' + else: + pass ## shouldn't happen + + +#/** +# ogUcastSendPartition +#@brief Función para enviar el contenido de una partición a multiples particiones remotas usando UNICAST. +#@param 1 disk +#@param 2 partition +#@param 3 sesionUcast +#@param 4 tool image +#@param 5 tool compresor +#@return +#@exception $OG_ERR_FORMAT +#@exception $OG_ERR_UCASTSENDPARTITION +#@note +#@todo: ogIsLocked siempre devuelve 1 +#*/ ## +#ogUcastSendPartition 1 2 8001:192.168.1.113 partclone lzop +def ogUcastSendPartition (disk, par, sess, tool, level): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return None + + FileSystemLib.ogUnmount (disk, par) + + cmd = ogUcastSyntax ('SENDPARTITION', sess, device=PART, tool=tool, level=level) + if not cmd: return None + print (f'nati cmd ({cmd})') + try: + subprocess.run (cmd, shell=True, check=True) + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_UCASTSENDPARTITION, ' ') + return None + + + +#/** +# ogUcastReceiverPartition +#@brief Función para recibir directamente en la partición el contenido de un fichero imagen remoto enviado por UNICAST. +#@param 1 disk +#@param 2 partition +#@param 3 session unicast +#@param 4 tool image +#@param 5 tool compresor +#@return +#@exception OG_ERR_FORMAT +#@exception OG_ERR_UCASTRECEIVERPARTITION +#@note +#@todo: +#*/ ## +#ogUcastReceiverPartition 1 1 8001:192.168.1.111 partclone lzop +def ogUcastReceiverPartition (disk, par, sess, tool, level): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return None + + FileSystemLib.ogUnmount (disk, par) + + cmd = ogUcastSyntax ('RECEIVERPARTITION', sess, device=PART, tool=tool, level=level) + if not cmd: return None + print (f'nati cmd ({cmd})') + try: + subprocess.run (cmd, shell=True, check=True) + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_UCASTRECEIVERPARTITION, ' ') + return None + + + +#/** +# ogUcastSendFile [ str_repo | int_ndisk int_npart ] /Relative_path_file sessionMulticast +#@brief Envía un fichero por unicast ORIGEN(fichero) DESTINO(sessionmulticast) +#@param (2 parámetros) $1 path_aboluto_fichero $2 sesionMcast +#@param (3 parámetros) $1 Contenedor REPO|CACHE $2 path_absoluto_fichero $3 sesionMulticast +#@param (4 parámetros) $1 disk $2 particion $3 path_absoluto_fichero $4 sesionMulticast +#@return +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception $OG_ERR_NOTFOUND +#@exception OG_ERR_UCASTSENDFILE +#@note Requisitos: +#*/ ## +# + +## TODO esta función es idéntica a ogMcastSendFile pero con s/Ucast/Mcast/; + +#ogUcastSendFile ([str_REPOSITORY] [int_ndisk int_npart] /Relative_path_file sesionMcast(puerto:ip:ip:ip)" \ +#ogUcastSendFile (disk=1, par=1, file='/aula1/winxp.img', sess='8000:172.17.36.11:172.17.36.12') +#ogUcastSendFile (container='REPO', file='/aula1/ubuntu.iso', sess='sesionUcast') +#ogUcastSendFile (container='CACHE', file='/aula1/winxp.img', sess='sesionUcast') +#ogUcastSendFile ( file='/opt/opengnsys/images/aula1/hd500.vmx', sess='sesionUcast') + +#ogUcastSendFile 1 2 /boot/vmlinuz-6.8.0-51-generic 8000:192.168.1.113 +#ogUcastSendFile 1 4 /swapfile.sys 8000:192.168.1.111 +#ogUcastSendFile REPO /ubu24.img 8000:192.168.1.111 +def ogUcastSendFile (disk=None, par=None, container=None, file=None, sess=None): + if file is None: + raise TypeError ('missing required argument: "file"') + if sess is None: + raise TypeError ('missing required argument: "sess"') + + if container is not None: + if disk is None and par is None: + ## we were given container= + source = FileLib.ogGetPath (src=container, file=file) + dev_err = f'{container} {file}' + print (f'nati ogGetPath (src=({container}), file=({file})) = source ({source})') + else: + raise TypeError ('argument "container" can be specified along neither "disk" nor "par"') + + else: + if disk is not None and par is not None: + ## we were given disk= par= + source = FileLib.ogGetPath (src=f'{disk} {par}', file=file) + dev_err = f'{disk} {par} {file}' + print (f'nati ogGetPath (src=({disk} {par}), file=({file})) = source ({source})') + elif disk is None and par is None: + ## we were given nothing + source = FileLib.ogGetPath (file=file) + dev_err = file + print (f'nati ogGetPath (file=({file})) = source ({source})') + else: + raise TypeError ('if one of "disk" and "par" are specified, then both must be') + + if not source: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found') + return + + path2 = FileLib.ogGetPath (file=source) + print (f'nati path2 ({path2})') + if not path2: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found') + return + + cmd = ogUcastSyntax ('SENDFILE', sess, file=source) + if not cmd: return None + print (f'nati cmd ({cmd})') + try: + subprocess.run (cmd, shell=True, check=True) + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_UCASTSENDFILE, ' ') + return None + +def _clientip(): + ipas = subprocess.run (['ip', '-json', 'address', 'show', 'up'], capture_output=True, text=True).stdout + ipasj = json.loads (ipas) + addresses = [] + for e in ipasj: + if 'lo' == e['ifname']: continue + if 'addr_info' not in e: continue + addrs = e['addr_info'] + for a in addrs: + if 'inet' != a['family']: continue + addresses.append ({ 'local': a['local'], 'prefixlen': a['prefixlen'] }) + return addresses + +def _binary_ip (ip): + for l in subprocess.run (['ipcalc', '--nocolor', ip ], capture_output=True, text=True).stdout.splitlines(): + if 'Address' not in l: continue + match = re.search (r'^(Address:)\s+(\S+)\s+(.*$)', l).group(3).replace (' ', '').replace ('.', '') + break + return match + +#/** +# ogMcastSyntax +#@brief Función para generar la instrucción de ejucción la transferencia de datos multicast +#@param 1 Tipo de operación [ SENDPARTITION RECEIVERPARTITION SENDFILE RECEIVERFILE ] +#@param 2 Sesión Mulicast +#@param 3 Dispositivo (opción PARTITION) o fichero(opción FILE) que será enviado. +#@param 4 Tools de clonación (opcion PARTITION) +#@param 5 Tools de compresion (opcion PARTITION) +#@return instrucción para ser ejecutada. +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception OG_ERR_NOTEXEC +#@exception OG_ERR_MCASTSYNTAXT +#@note Requisitos: upd-cast 2009 o superior +#@todo localvar check versionudp +#*/ ## +# + +#ogMcastSyntax SENDPARTITION 9000:full-duplex|half-duplex|broadcast:239.194.17.36:80M:50:60 device tools level +#ogMcastSyntax RECEIVERPARTITION 9000 device tools level +#ogMcastSyntax RECEIVERPARTITION 9000:172.17.88.161:40:120 device tools level + +#ogMcastSyntax SENDFILE 9000:full-duplex|half-duplex|broadcast:239.194.17.36:80M:50:60 file +#ogMcastSyntax RECEIVERFILE 9000 file +#ogMcastSyntax RECEIVERFILE 9000:172.17.88.161:40:120 file +def ogMcastSyntax (op, sess, file=None, device=None, tool=None, level=None): + if 'SENDPARTITION' == op or 'RECEIVERPARTITION' == op: + if device is None: + raise TypeError ('missing required argument: "device"') + if tool is None: + raise TypeError ('missing required argument: "tool"') + if tool.lower() not in ['partclone', 'partimage', 'ntfsclone']: + raise TypeError (f'argument "tool" has unsupported value "{tool}"') + if level is None: + raise TypeError ('missing required argument: "level"') + if level.lower() not in ['lzop', 'gzip', '0', '1']: + raise TypeError (f'argument "level" has unsupported value "{level}"') + elif 'SENDFILE' == op or 'RECEIVERFILE' == op: + if file is None: + raise TypeError ('missing required argument: "file"') + else: + raise TypeError ('first parameter should match (SEND|RECEIVER)(PARTITION|FILE), eg. "SENDFILE"') + + if 'SEND' in op: mode = 'server' + else: mode = 'client' + print (f'nati mode ({mode})') + + try: + isudpcast = subprocess.run (['udp-receiver', '--help'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTEXEC, 'upd-cast no existe') + return + + session = sess.split (':') + print (f'nati sess ({sess}) session ({session})') + + PERROR = 0 + if 'server' == mode: + if 6 != len (session): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'parametros session de servidor multicast no completa') + PERROR = 2 + elif 'client' == mode: + if 4 < len (session): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'parametros session de cliente multicast no completa') + PERROR = 2 + + mbuffer = " --pipe 'mbuffer -q -m 20M' " + portbase = int (session[0]) + print (f'nati portbase ({portbase})') + if portbase not in range (9000, 9100, 2): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession portbase {portbase}') + PERROR = 3 + + if 'server' == mode: + method, address, bitrate, nclients, maxtime = session[1:] + + if method.lower() not in ['full-duplex', 'half-duplex', 'broadcast']: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession method {method}') + PERROR = 4 + + if not StringLib.ogCheckIpAddress (address): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession address {address}') + PERROR = 5 + + ## the original regex has a backslash: ^[0-9]{1,3}\M$ + ## not sure why + if not re.search (r'^[0-9]{1,3}M$', bitrate): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession bitrate {bitrate}') + PERROR = 6 + + if not re.search (r'^[0-9]{1,10}$', nclients): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession nclients {nclients}') + PERROR = 7 + + if not re.search (r'^[0-9]{1,10}$', maxtime): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'McastSession maxtime {maxtime}') + PERROR = 8 + + cerror = '8x8/128' + syntaxserver = f'udp-sender {mbuffer} --nokbd --portbase {portbase} --{method} --mcast-data-address {address} --fec {cerror} --max-bitrate {bitrate} --ttl 16 --min-clients {nclients} --max-wait {maxtime} --autostart {maxtime} --log /tmp/mcast.log' + + if PERROR: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTSYNTAXT, f' {PERROR}') + return + + + if 'client' == mode: + other = session[1:] + print (f'nati session ({session}) other ({other})') + serveraddress = other[0] if len (other) > 0 else '' + starttimeout = other[1] if len (other) > 1 else '' + receivertimeout = other[2] if len (other) > 2 else '' + + ## serveraddres + if StringLib.ogCheckIpAddress (serveraddress): + serveraddress = f' --mcast-rdv-address {serveraddress}' + else: + repoip = NetLib.ogGetRepoIp() + clientip = _clientip() + #print (f'nati repoip ({repoip}) clientip ({clientip})') + if 1 != len (clientip): + raise Exception ('more than one local IP address found') + c = clientip[0] + #print (f'nati c ({c})') + clientip = c['local'] + mascara = c['prefixlen'] + #print (f'nati clientip ({clientip}) mascara ({mascara})') + + ripbt = _binary_ip (repoip) + ipbt = _binary_ip (clientip) + reposubred = ripbt[0:mascara] + clientsubred = ipbt[0:mascara] + #print (f'nati ripbt ({ripbt})') + #print (f'nati ipbt ({ipbt})') + #print (f'nati reposubred ({reposubred})') + #print (f'nati clientsubred ({clientsubred})') + if reposubred == clientsubred: serveraddress = ' ' + else: serveraddress = f' --mcast-rdv-address {repoip}' + + ## starttimeout + if re.search (r'^[0-9]{1,10}$', starttimeout): + if 0 == starttimeout: starttimeout = ' ' + else: starttimeout = f' --start-timeout {starttimeout}' + else: + starttimeout = f' --start-timeout {ogGlobals.MCASTERRORSESSION}' + if 'start-timeout' not in isudpcast: starttimeout = ' ' + + ## receivertimeout + if re.search (r'^[0-9]{1,10}$', receivertimeout): + if 0 == receivertimeout: receivertimeout = ' ' + else: receivertimeout = f' --receive-timeout {receivertimeout}' + else: + receivertimeout = f' --receive-timeout {ogGlobals.MCASTWAIT}' + if 'receive-timeout' not in isudpcast: receivertimeout = ' ' + + syntaxclient = f'udp-receiver {mbuffer} --portbase {portbase} {serveraddress} {starttimeout} {receivertimeout} --log /tmp/mcast.log' + + if 'SENDPARTITION' == op: + syn = ImageLib.ogCreateImageSyntax (device, ' ', tool, level) + ## REQUIRES package mbuffer to be installed!! + ## otherwise, param2 in ImageLib.ogCreateImageSyntax() is not '| mbuffer' but empty + ## and then parts[2] is out of range + parts = syn.split ('|') + #print (f'nati syn ({syn}) parts ({parts})') + prog1 = f'{parts[0]}|{parts[2]}'.strip() + prog1 = prog1.replace ('>', '').strip() + return f'{prog1} | {syntaxserver}' + + elif 'RECEIVERPARTITION' == op: + syn = ImageLib.ogRestoreImageSyntax (' ', device, tool, level) + parts = syn.split ('|') + compressor = parts[0].strip() + tools = parts[-1].strip() + return f'{syntaxclient} | {compressor} | {tools} ' + + elif 'SENDFILE' == op: + return f'{syntaxserver} --file {file}' + + elif 'RECEIVERFILE' == op: + return f'{syntaxclient} --file {file}' + + else: + raise Exception (f'unknown op ({op})--this should not happen') + + + +#/** +# ogMcastSendFile [ str_repo | int_ndisk int_npart ] /Relative_path_file sessionMulticast +#@brief Envía un fichero por multicast ORIGEN(fichero) DESTINO(sessionmulticast) +#@param (2 parámetros) $1 path_aboluto_fichero $2 sesionMcast +#@param (3 parámetros) $1 Contenedor REPO|CACHE $2 path_absoluto_fichero $3 sesionMulticast +#@param (4 parámetros) $1 disk $2 particion $3 path_absoluto_fichero $4 sesionMulticast +#@return +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception $OG_ERR_NOTFOUND +#@exception OG_ERR_MCASTSENDFILE +#*/ ## +# + +#ogMcastSendFile [str_REPOSITORY] [int_ndisk int_npart] /Relative_path_file sesionMcast" \ +#ogMcastSendFile (disk=1, par=1, file='/aula1/winxp.img', sess='sesionMcast') +#ogMcastSendFile (container='REPO', file='/aula1/ubuntu.iso', sess='sesionMcast') +#ogMcastSendFile (container='CACHE', file='/aula1/winxp.img', sess='sesionMcast') +#ogMcastSendFile ( file='/opt/opengnsys/images/aula1/hd500.vmx', sess='sesionMcast') + +#ogMcastSendFile 1 2 /boot/vmlinuz-6.8.0-51-generic 9000:full-duplex:239.194.37.31:50M:20:10 +#ogMcastSendFile REPO /ubu24.img 9000:full-duplex:239.194.37.31:50M:20:10 +#ogMcastSendFile /usr/lib64/ld-linux-x86-64.so.2 9000:full-duplex:239.194.37.31:50M:20:10 +def ogMcastSendFile (disk=None, par=None, container=None, file=None, sess=None): + if file is None: + raise TypeError ('missing required argument: "file"') + if sess is None: + raise TypeError ('missing required argument: "sess"') + + if container is not None: + if disk is None and par is None: + ## we were given container= + source = FileLib.ogGetPath (src=container, file=file) + dev_err = f'{container} {file}' + print (f'nati ogGetPath (src=({container}), file=({file})) = source ({source})') + else: + raise TypeError ('argument "container" can be specified along neither "disk" nor "par"') + + else: + if disk is not None and par is not None: + ## we were given disk= par= + source = FileLib.ogGetPath (src=f'{disk} {par}', file=file) + dev_err = f'{disk} {par} {file}' + print (f'nati ogGetPath (src=({disk} {par}), file=({file})) = source ({source})') + elif disk is None and par is None: + ## we were given nothing + source = FileLib.ogGetPath (file=file) + dev_err = file + print (f'nati ogGetPath (file=({file})) = source ({source})') + else: + raise TypeError ('if one of "disk" and "par" are specified, then both must be') + + if not source: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found') + return + + path2 = FileLib.ogGetPath (file=source) + print (f'nati path2 ({path2})') + if not path2: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or file {dev_err} not found') + return + + cmd = ogMcastSyntax ('SENDFILE', sess, file=source) + if not cmd: return None + print (f'nati cmd ({cmd})') + try: + subprocess.run (cmd, shell=True, check=True) + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTSENDFILE, ' ') + return None + + + +#/** +# ogMcastReceiverFile sesion Multicast [ str_repo | int_ndisk int_npart ] /Relative_path_file +#@brief Recibe un fichero multicast ORIGEN(sesionmulticast) DESTINO(fichero) +#@param (2 parámetros) $1 sesionMcastCLIENT $2 path_aboluto_fichero_destino +#@param (3 parámetros) $1 sesionMcastCLIENT $2 Contenedor REPO|CACHE $3 path_absoluto_fichero_destino +#@param (4 parámetros) $1 sesionMcastCLIENT $2 disk $3 particion $4 path_absoluto_fichero_destino +#@return +#@exception OG_ERR_FORMAT formato incorrecto. +#@exception $OG_ERR_MCASTRECEIVERFILE +#@note Requisitos: +#*/ ## +# + +#ogMcastReceiverFile ([ str_portMcast] [ [Relative_path_file] | [str_REPOSITORY path_file] | [int_ndisk int_npart path_file ] ]" \ +#ogMcastReceiverFile ( file='/PS1_PH1.img', sess='9000') +#ogMcastReceiverFile (container='CACHE', file='/aula1/PS2_PH4.img', sess='9000') +#ogMcastReceiverFile (disk=1, par=1, file='/isos/linux.iso', sess='9000') + +#ogMcastReceiverFile 9000:full-duplex:239.194.37.31 1 4 /hola +def ogMcastReceiverFile (disk=None, par=None, container=None, file=None, sess=None): + if file is None: + raise TypeError ('missing required argument: "file"') + if sess is None: + raise TypeError ('missing required argument: "sess"') + + if container is not None: + if disk is None and par is None: + ## we were given container= + targetdir = FileLib.ogGetParentPath (src=container, file=file) + dev_err = f'{container} {file}' + print (f'nati ogGetParentPath (src=({container}), file=({file})) = targetdir ({targetdir})') + else: + raise TypeError ('argument "container" can be specified along neither "disk" nor "par"') + + else: + if disk is not None and par is not None: + ## we were given disk= par= + targetdir = FileLib.ogGetParentPath (src=f'{disk} {par}', file=file) + dev_err = f'{disk} {par} {file}' + print (f'nati ogGetParentPath (src=({disk} {par}), file=({file})) = targetdir ({targetdir})') + elif disk is None and par is None: + ## we were given nothing + targetdir = FileLib.ogGetParentPath (file=file) + dev_err = file + print (f'nati ogGetParentPath (file=({file})) = targetdir ({targetdir})') + else: + raise TypeError ('if one of "disk" and "par" are specified, then both must be') + + if not targetdir: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'target directory {targetdir} not found') + return + + targetfile = os.path.basename (file) + print (f'nati targetfile ({targetfile})') + + print (f'nati calling ogMcastSyntax with sess ({sess})') + cmd = ogMcastSyntax ('RECEIVERFILE', sess, file=os.path.join (targetdir, targetfile)) + if not cmd: return None + print (f'nati cmd ({cmd})') + try: + subprocess.run (cmd, shell=True, check=True) + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTRECEIVERFILE, targetfile) + return None + + +#/** +# ogMcastSendPartition +#@brief Función para enviar el contenido de una partición a multiples particiones remotas. +#@param 1 disk +#@param 2 partition +#@param 3 session multicast +#@param 4 tool clone +#@param 5 tool compressor +#@return +#@exception OG_ERR_FORMAT +#@exception OG_ERR_MCASTSENDPARTITION +#@note +#@todo: ogIsLocked siempre devuelve 1. crear ticket +#*/ ## + +#ogMcastSendPartition (disk, par, SessionMulticastSERVER, tools, compresor) +#ogMcastSendPartition (1, 1, '9000:full-duplex:239.194.37.31:50M:20:2', 'partclone', 'lzop') +#ogMcastSendPartition 1 2 9000:full-duplex:239.194.37.31:50M:20:10 partclone lzop +def ogMcastSendPartition (disk, par, sess, tool, compressor): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return + + FileSystemLib.ogUnmount (disk, par) + cmd = ogMcastSyntax ('SENDPARTITION', sess, device=PART, tool=tool, level=compressor) + if not cmd: return None + print (f'nati cmd ({cmd})') + try: + subprocess.run (cmd, shell=True, check=True) + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTSENDPARTITION, ' ') + return None + +#/** +# ogMcastReceiverPartition +#@brief Función para recibir directamente en la partición el contenido de un fichero imagen remoto enviado por multicast. +#@param 1 disk +#@param 2 partition +#@param 3 session multicast +#@param 4 tool clone +#@param 5 tool compressor +#@return +#@exception $OG_ERR_FORMAT +#*/ ## +#ogMcastReceiverPartition 1 1 9000:full-duplex:239.194.37.31 partclone lzop +def ogMcastReceiverPartition (disk, par, sess, tool, compressor): + PART = DiskLib.ogDiskToDev (disk, par) + if not PART: return + + FileSystemLib.ogUnmount (disk, par) + cmd = ogMcastSyntax ('RECEIVERPARTITION', sess, device=PART, tool=tool, level=compressor) + if not cmd: return None + print (f'nati cmd ({cmd})') + try: + subprocess.run (cmd, shell=True, check=True) + except subprocess.CalledProcessError: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_MCASTRECEIVERPARTITION, ' ') ## original code has OG_ERR_MCASTSENDPARTITION + return None + + + +#/** +# ogMcastRequest +#@brief Función temporal para solicitar al ogRepoAux el envio de un fichero por multicast +#@param 1 Fichero a enviar ubicado en el REPO. puede ser ruta absoluta o relatica a /opt/opengnsys/images +#@param 2 PROTOOPT opciones protocolo multicast +#*/ ## +## now ogCore takes this responsibility +def ogMcastRequest (img, proto): + return True + + +########################################## +############## funciones torrent +#/** +# ogTorrentStart [ str_repo | int_ndisk int_npart ] Relative_path_file.torrent | SessionProtocol +#@brief Función iniciar P2P - requiere un tracker para todos los modos, y un seeder para los modos peer y leecher y los ficheros .torrent. +#@param str_pathDirectory str_Relative_path_file +#@param int_disk int_partition str_Relative_path_file +#@param str_REPOSITORY(CACHE - LOCAL) str_Relative_path_file +#@param (2 parámetros) $1 path_aboluto_fichero_torrent $2 Parametros_Session_Torrent +#@param (3 parámetros) $1 Contenedor CACHE $2 path_absoluto_fichero_Torrent $3 Parametros_Session_Torrent +#@param (4 parámetros) $1 disk $2 particion $3 path_absoluto_fichero_Torrent 4$ Parametros_Session_Torrent +#@return +#@note protocoloTORRENT=mode:time mode=seeder -> Dejar el equipo seedeando hasta que transcurra el tiempo indicado o un kill desde consola, mode=peer -> seedear mientras descarga mode=leecher -> NO seedear mientras descarga time tiempo que una vez descargada la imagen queremos dejar al cliente como seeder. +#*/ ## +#ogTorrentStart ( torrentfile='/opt/opengnsys/cache/linux.iso', torrentsess='peer:60') +#ogTorrentStart (container='CACHE', torrentfile='/PS1_PH1.img.torrent', torrentsess='seeder:10000') +#ogTorrentStart (disk=1, par=1, torrentfile='/linux.iso.torrent', torrentsess='leecher:60') +#ogTorrentStart /opt/opengnsys/cache/opt/opengnsys/images/ubu24.EXTFS.torrent seeder:10000 +#ogTorrentStart 1 4 /opt/opengnsys/images/ubu24.EXTFS.torrent seeder:10000 +#ogTorrentStart CACHE /ubu24.EXTFS.torrent seeder:10000 +def ogTorrentStart (disk=None, par=None, container=None, torrentfile=None, torrentsess=None): + if torrentfile is None: + raise TypeError ('missing required argument: "torrentfile"') + if torrentsess is None: + raise TypeError ('missing required argument: "torrentsess"') + + if container is not None: + if disk is None and par is None: + ## we were given container= + if 'CACHE' != container.upper(): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'La descarga torrent solo se hace desde local, copia el torrent a la cache y realiza la operación desde esa ubicación') + return None + source = FileLib.ogGetPath (src=container, file=torrentfile) + dev_err = f'{container} {torrentfile}' + print (f'nati ogGetPath (src=({container}), file=({torrentfile})) = source ({source})') + else: + raise TypeError ('argument "container" can be specified along neither "disk" nor "par"') + + else: + if disk is not None and par is not None: + ## we were given disk= par= + source = FileLib.ogGetPath (src=f'{disk} {par}', file=torrentfile) + dev_err = f'{disk} {par} {torrentfile}' + print (f'nati ogGetPath (src=({disk} {par}), file=({torrentfile})) = source ({source})') + elif disk is None and par is None: + ## we were given nothing + if torrentfile.startswith ('/opt/opengnsys/images'): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'La descarga torrent solo se hace desde local, copia el torrent a la cache y realiza la operación desde esa ubicación') + return None + source = FileLib.ogGetPath (file=torrentfile) + dev_err = torrentfile + print (f'nati ogGetPath (file=({torrentfile})) = source ({source})') + else: + raise TypeError ('if one of "disk" and "par" are specified, then both must be') + + if not source: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'device or torrentfile {dev_err} not found') + return + + if subprocess.run (['ctorrent', '-x', source]).returncode: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, '') + return None + + target = re.sub (r'\.torrent$', '', source) + dirsource = FileLib.ogGetParentPath (file=source) + + ERROR = None + sess = torrentsess.split (':') + if 2 != len (sess): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'parametros session Torrent no completa: modo:tiempo') + return None + + mode = sess[0].lower() + if mode not in ['seeder', 'peer', 'leecher']: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'valor modo Torrent no valido {sess[0]}') + return None + + time = sess[1] + if not re.search (r'^[0-9]{1,10}$', time): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'valor tiempo no valido {sess[1]}') + return None + time = int (time) + + OPTION = None + cwd = os.getcwd() + # si No fichero .bf, y Si fichero destino imagen ya descargada y su chequeo fue comprobado en su descarga inicial. + if not os.path.exists (f'{source}.bf') and os.path.exists (target): + print ('imagen ya descargada') + if 'seeder' != mode: return 'success' ## return any true value + + print ('MODE seeder ctorrent') + os.chdir (dirsource) + subprocess.run (['timeout', '--signal', 'INT', time, 'ctorrent', '-f', source]) + os.chdir (cwd) + return 'success' + + #Si no existe bf ni fichero destino descarga inicial. + if not os.path.exists (f'{source}.bf') and not os.path.exists (target): + print ('descarga inicial') + OPTION = 'DOWNLOAD' + + # Si fichero bf descarga anterior no completada -. + if os.path.exists (f'{source}.bf') and os.path.exists (target): + print ('Continuar con Descargar inicial no terminada.') + OPTION = 'DOWNLOAD' + + if 'DOWNLOAD' != OPTION: return 'success' + + os.chdir (dirsource) + if 'peer' == mode: + print ('Donwloading Torrent as peer') + # Creamos el fichero de resumen por defecto + open (f'{source}.bf', 'w').close() + # ctorrent controla otro fichero -b ${SOURCE}.bfog + subprocess.run (['ctorrent', '-f', '-c', '-X', f'sleep {time}; kill -2 $(pidof ctorrent)', '-C', '100', source, '-s', target, '-b', f'{source}.bfog']) + elif 'leecher' == mode: + print ('Donwloading Torrent as leecher') + subprocess.run (['ctorrent', '${SOURCE}', '-X', 'sleep 30; kill -2 $(pidof ctorrent)', '-C', '100', '-U', '0']) + elif 'seeder' == mode: + print ('MODE seeder ctorrent') + # Creamos el fichero de resumen por defecto + open (f'{source}.bf', 'w').close() + # ctorrent controla otro fichero -b ${SOURCE}.bfog + subprocess.run (['ctorrent', '-f', '-c', '-X', f'sleep {time}; kill -2 $(pidof ctorrent)', '-C', '100', source, '-s', target, '-b', f'{source}.bfog']) + else: + print ('this should not happen') + return None + + os.chdir (cwd) + + +#/** +# ogCreateTorrent [ str_repo | int_ndisk int_npart ] Relative_path_file +#@brief Función para crear el fichero torrent. +#@param str_pathDirectory str_Relative_path_file +#@param int_disk int_partition str_Relative_path_file +#@param str_REPOSITORY(CACHE - LOCAL) str_Relative_path_file +#@return +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Disco o particion no corresponden con un dispositivo. +#@exception OG_ERR_PARTITION Tipo de partición desconocido o no se puede montar. +#@exception OG_ERR_NOTOS La partición no tiene instalado un sistema operativo. +#*/ ## + +#ogCreateTorrent ([str_REPOSITORY] [int_ndisk int_npart] Relative_path_file IpBttrack) +#ogCreateTorrent (disk=1, par=1, file='/aula1/winxp', ip_bttrack='10.1.15.23') +#ogCreateTorrent (container='REPO', file='/aula1/winxp', ip_bttrack='10.1.15.45') +#ogCreateTorrent (container='CACHE', file='/aula1/winxp', ip_bttrack='10.1.15.45') +def ogCreateTorrent (disk=None, par=None, container=None, file=None, ip_bttrack=None): + if file is None: + raise TypeError ('missing required argument: "file"') + if ip_bttrack is None: + raise TypeError ('missing required argument: "ip_bttrack"') + + from_cache = False + + if container is not None: + if disk is None and par is None: + ## we were given container= + if 'CACHE' == container: from_cache = True + ext = ImageLib.ogGetImageType (container, file) + if ext is None: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{container} {file}') + return + f = f'{file}.{ext}' + source = FileLib.ogGetPath (src=container, file=f) + print (f'nati ogGetPath (src=({container}), file=({f})) = source ({source})') + else: + raise TypeError ('argument "container" can be specified along neither "disk" nor "par"') + + else: + if disk is not None and par is not None: + ## we were given disk= par= + f = f'{file}.img' + source = FileLib.ogGetPath (src=f'{disk} {par}', file=f) + print (f'nati ogGetPath (src=({disk} {par}), file=({f})) = source ({source})') + elif disk is None and par is None: + ## we were given nothing + f = f'{file}.img' + source = FileLib.ogGetPath (file=f) + print (f'nati ogGetPath (file=({f})) = source ({source})') + else: + raise TypeError ('if one of "disk" and "par" are specified, then both must be') + + if not source: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, '') + return + + if from_cache: + if not CacheLib.ogFindCache(): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, "CACHE") + #return None + + if os.path.exists (f'{source}.torrent'): + os.rename (f'{source}.torrent', f'{source}.torrent.ant') + print ('Esperamos que se refresque el servidor') + time.sleep (20) + + cwd = os.getcwd() + os.chdir (os.path.dirname (source)) + print (f'ctorrent -t {os.path.basename (source)} -u http://{ip_bttrack}:6969/announce -s {source}.torrent') + subprocess.run (['ctorrent', '-t', os.path.basename (source), '-u', f'http://{ip_bttrack}:6969/announce', '-s', f'{source}.torrent']) + os.chdir (cwd) + + +#/** +# ogUpdateCacheIsNecesary [ str_repo ] Relative_path_file_OGIMG_with_/ +#@brief Comprueba que el fichero que se desea almacenar en la cache del cliente, no esta. +#@param 1 str_REPO +#@param 2 str_Relative_path_file_OGIMG_with_/ +#@param 3 md5 to check: use full to check download image torrent +#@return True cache sin imagen, SI es necesario actualizar el fichero. +#@return False imagen en la cache, NO es necesario actualizar el fichero +#@return None error de sintaxis (TODO) +#@note +#@todo: Proceso en el caso de que el fichero tenga el mismo nombre, pero su contenido sea distinto. +#@todo: Se dejan mensajes mientras se confirma su funcionamiento. +#*/ ## +#ogUpdateCacheIsNecesary ('REPO', '/PS1_PH1.img', 'UNICAST') +#ogUpdateCacheIsNecesary ('REPO', '/ogclient.sqfs', 'FULL') +#ogUpdateCacheIsNecesary ('REPO', '/ogclient.sqfs', 'TORRENT') +def ogUpdateCacheIsNecesary (repo, file, proto): + if not CacheLib.ogFindCache(): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTCACHE, '') + return None + + if repo.lower() != 'repo': + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {repo} {file}') + return None + + filesource = FileLib.ogGetPath (src=repo, file=file) + #print (f'nati filesource ({filesource})') + if not filesource: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f' {repo} {file}') + return None + + # paso 1. si no existe la imagen, confirmar que es necesario actualizar la cache. + filetarget = FileLib.ogGetPath (src='CACHE', file=file) + #print (f'nati filetarget ({filetarget})') + if not filetarget: + # borramos el fichero bf del torrent, en el caso de que se hubiese quedado de algun proceso fallido + if FileLib.ogGetPath (src='CACHE', file=f'/{file}.torrent.bf'): ogDeleteFile (container='CACHE', file=f'{file}.torrent.bf') + if FileLib.ogGetPath (src='CACHE', file=f'/{file}.sum'): ogDeleteFile (container='CACHE', file=f'{file}.sum') + if FileLib.ogGetPath (src='CACHE', file=f'/{file}.full.sum'): ogDeleteFile (container='CACHE', file=f'{file}.full.sum') + print ('TRUE(0), es necesario actualizar. Paso 1, la cache no contiene esa imagen ') + return True + + # Paso 2. Comprobamos que la imagen no estuviese en un proceso previo torrent + if FileLib.ogGetPath (file=f'{filetarget}.torrent.bf'): + #TODO: comprobar los md5 del fichero .torrent para asegurarnos que la imagen a descarga es la misma. + print ('TRUE(0), es necesario actualizar. Paso 2, la imagen esta en un estado de descarga torrent interrumpido') + return True + + ## En este punto la imagen en el repo y en la cache se llaman igual, + # paso 4. Obtener los md5 del fichero imagen en la cacha segun PROTOCOLO $3 + if proto.lower() in ['full', 'torrent']: + #Buscamos MD5 en el REPO SOURCE + if os.path.exists (f'{filesource}.full.sum'): + with open (f'{filesource}.full.sum', 'r') as fd: + md5source = fd.read().strip() + else: + md5source = FileLib.ogCalculateFullChecksum (file=filesource) + + # Generamos el MD5 (full) en la CACHE + if not os.path.exists (f'{filetarget}.full.sum'): + fullck = FileLib.ogCalculateFullChecksum (file=filetarget) + with open (f'{filetarget}.full.sum', 'w') as fd: + fd.write (fullck + '\n') + with open (f'{filetarget}.full.sum', 'r') as fd: + md5target = fd.read().strip() + # Generamos el MD5 (little) en la CACHE para posteriores usos del protocolo MULTICAST + if not os.path.exists (f'{filetarget}.sum'): + ck = FileLib.ogCalculateChecksum (file=filetarget) + with open (f'{filetarget}.sum', 'w') as fd: + fd.write (ck + '\n') + else: + #Buscamos MD5 en el REPO SOURCE + if os.path.exists (f'{filesource}.sum'): + with open (f'{filesource}.sum', 'r') as fd: + md5source = fd.read().strip() + else: + md5source = FileLib.ogCalculateChecksum (file=filesource) + + # Generamos el MD5 (little) en la CACHE + if not os.path.exists (f'{filetarget}.sum'): + ck = FileLib.ogCalculateChecksum (file=filetarget) + with open (f'{filetarget}.sum', 'w') as fd: + fd.write (ck + '\n') + with open (f'{filetarget}.sum', 'r') as fd: + md5target = fd.read().strip() + #Generamos o copiamos MD5 (full) en la CACHE para posteriores usos con Torrent + # Si no existe el full.sum y si existe el .sum es porque el upateCACHE multicast o unicast ha sido correcto. + if not os.path.exists (f'{filetarget}.full.sum') and os.path.exists (f'{filetarget}.sum'): + if os.path.exists (f'{filesource}.full.sum'): + #Existe el .full.sum en REPO realizamos COPIA + shutil.copy2 (f'{filesource}.full.sum', f'{filetarget}.full.sum') + else: + #No existe .full.sum no en REPO LO GENERAMOS en la cache: situacion dificil que ocurra + fullck = FileLib.ogCalculateFullChecksum (file=filetarget) + with open (f'{filetarget}.full.sum', 'w') as fd: + fd.write (fullck + '\n') + + # Paso 5. comparar los md5 + if md5source == md5target: + print ('FALSE (1), No es neceario actualizar. Paso5.A la imagen esta en cache') + return False + else: + print ('imagen en cache distinta, borramos la imagen anterior') + for f in [f'{filetarget}', f'{filetarget}.sum', f'{filetarget}.torrent', f'{filetarget}.full.sum']: + os.unlink (f) + print ('TRUE (0), Si es necesario actualizar.') + return True diff --git a/client/lib/python3/RegistryLib.py b/client/lib/python3/RegistryLib.py new file mode 100644 index 0000000..2657bd8 --- /dev/null +++ b/client/lib/python3/RegistryLib.py @@ -0,0 +1,382 @@ +#/** +#@file RegistryLib.py +#@brief Librería o clase Registry +#@class Boot +#@brief Funciones para gestión del registro de Windows. +#@warning License: GNU GPLv3+ +#*/ + +import subprocess +import os +import re +import shutil +import tempfile + +import ogGlobals +import SystemLib +import FileLib + +# Función ficticia para lanzar chntpw con timeout de 5 s., evitando cuelgues del programa. +chntpw_exe = shutil.which ('drbl-chntpw') or shutil.which ('chntpw') +def chntpw (hivefile, input_file): + #print (f'nati: hivefile ({hivefile}) input_file ({input_file}) type ({type(input_file)})') + with open (input_file, 'r') as fd: + input_contents = fd.read() + #print (f'nati: input_contents ({input_contents})') + return subprocess.run ([chntpw_exe, '-e', hivefile], timeout=5, input=input_contents, capture_output=True, text=True).stdout + +## en el codigo bash aparecen "${3%\\*}" y "${3##*\\}" varias veces +## ${3%\\*} es el "dirname" de una key del registro +## ${3##*\\} es el "basename" +def _split_k (k): + k_elems = k.split ('\\') + k_dirname = '\\'.join (k_elems[0:-1]) + k_basename = k_elems[-1] + return k_dirname, k_basename + +#/** +# ogAddRegistryKey path_mountpoint str_hive str_keyname +#@brief Añade una nueva clave al registro de Windows. +#@param path_mountpoint directorio donde está montado el sistema Windows +#@param str_hive sección del registro +#@param str_keyname nombre de la clave +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado. +#@note hive = { default, sam, security, software, system, components } +#@warning Requisitos: chntpw +#@warning El sistema de archivos de Windows debe estar montada previamente. +#*/ ## +def ogAddRegistryKey (mntpt, hive, k): + hivefile = ogGetHivePath (mntpt, hive) + if not hivefile: return + + k_dirname, k_basename = _split_k (k) + + with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f: + f.write (f'cd {k_dirname}\n') + f.write (f'nk {k_basename}\n') + f.write ('q\ny\n') + f.close() + chntpw (hivefile, f.name) + os.remove (f.name) + +#/** +# ogAddRegistryValue path_mountpoint str_hive str_valuename [str_valuetype] +#@brief Añade un nuevo valor al registro de Windows, indicando su tipo de datos. +#@param path_mountpoint directorio donde está montado el sistema Windows +#@param str_hive sección del registro +#@param str_valuename nombre del valor +#@param str_valuetype tipo de datos del valor (opcional) +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado. +#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS } +#@note valuetype = { STRING, BINARY, DWORD }, por defecto: STRING +#@warning Requisitos: chntpw +#@warning El sistema de archivos de Windows debe estar montada previamente. +#*/ ## +#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1') ## type STRING by default +#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1', 'STRING') +#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1', 'BINARY') +#ogAddRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1', 'DWORD') +def ogAddRegistryValue (mntpt, hive, k, vtype='STRING'): + hivefile = ogGetHivePath (mntpt, hive) + if not hivefile: return + + k_dirname, k_basename = _split_k (k) + + # Determine the value type. + if 'STRING' == vtype.upper(): TYPE = 1 + elif 'BINARY' == vtype.upper(): TYPE = 3 + elif 'DWORD' == vtype.upper(): TYPE = 4 + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_OUTOFLIMIT, vtype) + return + + with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f: + f.write (f'cd {k_dirname}\n') + f.write (f'nv {TYPE} {k_basename}\n') + f.write ('q\ny\n') + f.close() + chntpw (hivefile, f.name) + os.remove (f.name) + + +#/** +# ogDeleteRegistryKey path_mountpoint str_hive str_keyname +#@brief Elimina una clave del registro de Windows con todo su contenido. +#@param path_mountpoint directorio donde está montado el sistema Windows +#@param str_hive sección del registro +#@param str_keyname nombre de la clave +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado. +#@note hive = { default, sam, security, software, system, components } +#@warning Requisitos: chntpw +#@warning El sistema de archivos de Windows debe estar montada previamente. +#@warning La clave debe estar vacía para poder ser borrada. +#*/ ## +def ogDeleteRegistryKey (mntpt, hive, k): + hivefile = ogGetHivePath (mntpt, hive) + if not hivefile: return + + k_dirname, k_basename = _split_k (k) + + with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f: + f.write (f'cd {k_dirname}\n') + f.write (f'dk {k_basename}\n') + f.write ('q\ny\n') + f.close() + chntpw (hivefile, f.name) + os.remove (f.name) + + +#/** +# ogDeleteRegistryValue path_mountpoint str_hive str_valuename +#@brief Elimina un valor del registro de Windows. +#@param path_mountpoint directorio donde está montado el sistema Windows +#@param str_hive sección del registro +#@param str_valuename nombre del valor +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado. +#@note hive = { default, sam, security, software, system, components } +#@warning Requisitos: chntpw +#@warning El sistema de archivos de Windows debe estar montada previamente. +#*/ ## +#ogDeleteRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Microsoft\NewKey\Value1') +def ogDeleteRegistryValue (mntpt, hive, k): + hivefile = ogGetHivePath (mntpt, hive) + if not hivefile: return + + k_dirname, k_basename = _split_k (k) + + with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f: + f.write (f'cd {k_dirname}\n') + f.write (f'dv {k_basename}\n') + f.write ('q\ny\n') + f.close() + chntpw (hivefile, f.name) + os.remove(f.name) + + +#/** +# ogGetHivePath path_mountpoint [str_hive|str_user] +#@brief Función básica que devuelve el camino del fichero con una sección del registro. +#@param path_mountpoint directorio donde está montado el sistema Windows +#@param str_hive sección del registro +#@return str_path - camino del fichero de registro +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado. +#@note hive = { DEFAULT, SAM, SECURITY, SOFTWARE, SYSTEM, COMPONENTS, NombreDeUsuario } +#@warning El sistema de archivos de Windows debe estar montada previamente. +#*/ ## +#ogGetHivePath ('/mnt/sda1', 'user1') => /mnt/sda1/Users/user1/NTUSER.DAT +#ogGetHivePath ('/mnt/sda1', 'SYSTEM') => //mnt/sda1/Windows/System32/config/SYSTEM +#ogGetHivePath ('/mnt/sda1', 'IEUser') => //mnt/sda1/Users/IEUser/NTUSER.DAT +def ogGetHivePath(mntpt, hive): + # Camino del fichero de registro de usuario o de sistema (de menor a mayor prioridad). + FILE = FileLib.ogGetPath(file=f"/{mntpt}/Windows/System32/config/{hive}") + if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/Users/{hive}/NTUSER.DAT") + if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/winnt/system32/config/{hive}") + if not FILE: FILE = FileLib.ogGetPath(file=f"/{mntpt}/Documents and Settings/{hive}/NTUSER.DAT") + if FILE and os.path.isfile(FILE): + return FILE + else: + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_NOTFOUND, f'{mntpt} {hive}') + return None + + +## simulate 'grep --after-context 1' +def _grep_A1 (strings, search_term): + results = [] + for i in range (len (strings)): + if search_term in strings[i]: + results.append (strings[i]) + if i + 1 < len(strings): + results.append (strings[i + 1]) + + return results + +#/** +# ogGetRegistryValue path_mountpoint str_hive str_valuename +#@brief Devuelve el dato de un valor del registro de Windows. +#@param path_mountpoint directorio donde está montado el sistema Windows +#@param str_hive sección del registro +#@param str_valuename nombre del valor +#@return str_valuedata - datos del valor. +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado. +#@note hive = { default, sam, security, software, system, components } +#@warning Requisitos: chntpw, awk +#@warning El sistema de archivos de Windows debe estar montado previamente. +#*/ ## +def ogGetRegistryValue (mntpt, hive, k): + hivefile = ogGetHivePath(mntpt, hive) + if not hivefile: return + + k_dirname, k_basename = _split_k (k) + + with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f: + f.write (f'cd {k_dirname}\n') + f.write (f'cat {k_basename}\n') + f.write ('q\n') + f.close() + chntpw_out = chntpw (hivefile, f.name) + os.remove (f.name) + + lines = chntpw_out.splitlines() + lines = _grep_A1 (lines, '> Value') + if 2 != len (lines): + return None + + ret = None + if 'REG_BINARY' in lines[0]: + if re.search ('^:[0-9A-F]+ ', lines[1]): + ret = lines[1][8:56] + else: + ret = lines[1] + return ret + + +#/** +# ogListRegistryKeys path_mountpoint str_hive str_key +#@brief Lista los nombres de subclaves de una determinada clave del registro de Windows. +#@param path_mountpoint directorio donde está montado el sistema Windows +#@param str_hive sección del registro +#@param str_key clave de registro +#@return str_subkey ... - lista de subclaves +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado. +#@note hive = { default, sam, security, software, system, components } +#@warning Requisitos: chntpw, awk +#@warning El sistema de archivos de Windows debe estar montado previamente. +#*/ ## +#ogListRegistryKeys ('/mnt/sda1', 'SOFTWARE', '\Microsoft\Windows\CurrentVersion') +def ogListRegistryKeys (mntpt, hive, k): + hivefile = ogGetHivePath(mntpt, hive) + if not hivefile: return + + with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f: + f.write (f'ls {k}\n') + f.write ('q\n') + f.close() + chntpw_out = chntpw (hivefile, f.name) + os.remove (f.name) + + lines = chntpw_out.splitlines() + ret = [] + for l in lines: + elems = re.split ('[<>]', l) + if len(elems) < 2: continue + if ' ' == elems[0]: + ret.append (elems[1]) + return ret + + +#/** +# ogListRegistryValues path_mountpoint str_hive str_key +#@brief Lista los nombres de valores de una determinada clave del registro de Windows. +#@param path_mountpoint directorio donde está montado el sistema Windows +#@param str_hive sección del registro +#@param str_key clave de registro +#@return str_value ... - lista de valores +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado. +#@note hive = { default, sam, security, software, system, components } +#@warning Requisitos: chntpw, awk +#@warning El sistema de archivos de Windows debe estar montado previamente. +#*/ ## +#ogListRegistryValues ('/mnt/sda1', 'SOFTWARE', '\Microsoft\Windows\CurrentVersion') +def ogListRegistryValues (mntpt, hive, k): + hivefile = ogGetHivePath(mntpt, hive) + if not hivefile: return + + with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f: + f.write (f'ls {k}\n') + f.write ('q\n') + f.close() + chntpw_out = chntpw (hivefile, f.name) + os.remove (f.name) + + lines = chntpw_out.splitlines() + ret = [] + for l in lines: + elems = re.split ('[<>]', l) + if len(elems) < 2: continue + if 'REG_' in elems[0]: + ret.append (elems[1]) + return ret + + +def _format_hex (hex_string): + result = [] + offset = 0 + + hex_values = hex_string.strip().split() + result.append (str (len (hex_values))) + + while hex_values: + chunk = hex_values[:16] + hex_values = hex_values[16:] + + offset_str = f':{offset:05x} ' + hex_line = ' '.join (chunk) + result.append (offset_str + hex_line) + + offset += 16 + + return '\n'.join (result) + +#/** +# ogSetRegistryValue path_mountpoint str_hive str_valuename str_valuedata +#@brief Establece el dato asociado a un valor del registro de Windows. +#@param path_mountpoint directorio donde está montado el sistema Windows +#@param str_hive sección del registro +#@param str_valuename nombre del valor de registro +#@param str_valuedata dato del valor de registro +#@return (nada) +#@exception OG_ERR_FORMAT Formato incorrecto. +#@exception OG_ERR_NOTFOUND Fichero de registro no encontrado. +#@note hive = { default, sam, security, software, system, components } +#@warning Requisitos: chntpw +#@warning El sistema de archivos de Windows debe estar montado previamente. +#*/ ## +#ogSetRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Key\SubKey\StringValue', 'Abcde Fghij') +#ogSetRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Key\SubKey\DwordValue', 1) +#ogSetRegistryValue ('/mnt/sda1', 'SOFTWARE', '\Key\SubKey\BinaryValue', '04 08 0C 10') +def ogSetRegistryValue (mntpt, hive, k, v): + hivefile = ogGetHivePath (mntpt, hive) + if not hivefile: return + + k_dirname, k_basename = _split_k (k) + + with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f: + f.write (f"ls {k_dirname}\n") + f.write ('q\n') + f.close() + chntpw_out = chntpw (hivefile, f.name) + os.remove(f.name) + + if re.search (f"BINARY.*<{k_basename}>", chntpw_out): + ## the entry in the registry is binary. Our input should be a sequence of bytes + + if ' ' != v[-1]: v += ' ' ## the regex below requires a trailing space + if not re.match (r'^([0-9A-F]{2} )*$', v.upper()): + SystemLib.ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, f'"{v}"') + return + + formatted = _format_hex (v.upper()) + formatted += '\ns' + else: + formatted = v + + with tempfile.NamedTemporaryFile (delete_on_close=False, prefix='chntpw-', mode='w') as f: + f.write (f'cd {k_dirname}\n') + f.write (f'ed {k_basename}\n') + f.write (f'{formatted}\n') + f.write ('q\ny\n') + f.close() + chntpw (hivefile, f.name) + os.remove(f.name) diff --git a/client/lib/python3/StringLib.py b/client/lib/python3/StringLib.py new file mode 100644 index 0000000..eda1c93 --- /dev/null +++ b/client/lib/python3/StringLib.py @@ -0,0 +1,31 @@ +import re + + + +#/** +# ogCheckIpAddress +#@brief Función para determinar si una cadena es una dirección ipv4 válida +#@param 1 string de la ip a comprobar +#@return 0 si es una dirección válida +#@return 1 si NO es una dirección válida +#@exception OG_ERR_FORMAT formato incorrecto. +#@note +#@todo +#*/ ## +def ogCheckIpAddress(ip): + """ + Función para determinar si una cadena es una dirección ipv4 válida. + + :param ip: string de la ip a comprobar + :return: True si es una dirección válida, False si NO es una dirección válida + """ + if not isinstance(ip, str): + raise ValueError("Formato incorrecto, el parámetro debe ser una cadena.") + + regex = r"^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" + if re.match(regex, ip): + parts = ip.split('.') + if all(0 <= int(part) <= 255 for part in parts): + return True + return False + diff --git a/client/lib/python3/SystemLib.py b/client/lib/python3/SystemLib.py new file mode 100644 index 0000000..fffd2cb --- /dev/null +++ b/client/lib/python3/SystemLib.py @@ -0,0 +1,310 @@ +import subprocess +import datetime +from zoneinfo import ZoneInfo +import sys +import os +import shutil +import inspect +import glob + +## for ogExecAndLog +from io import StringIO +from contextlib import redirect_stdout, redirect_stderr + +import ogGlobals +import StringLib +import SystemLib + +#NODEBUGFUNCTIONS, OGIMG, OG_ERR_CACHESIZE, OG_ERR_NOTCACHE, OG_ERR_NOTWRITE, OG_ERR_FILESYS +#OG_ERR_REPO, OG_ERR_NOTOS, OG_ERR_NOGPT, OG_ERR_OUTOFLIMIT, OG_ERR_IMAGE, OG_ERR_CACHE +#OGLOGSESSION, OGLOGCOMMAND, OGLOGFILE, OG_ERR_LOCKED, OG_ERR_PARTITION, OG_ERR_FORMAT, OG_ERR_NOTEXEC, OG_ERR_NOTFOUND + +def _logtype2logfile (t): + if 'log' == t.lower(): return ogGlobals.OGLOGFILE + elif 'command' == t.lower(): return ogGlobals.OGLOGCOMMAND + elif 'session' == t.lower(): return ogGlobals.OGLOGSESSION + else: raise Exception (f'unknown log type ({t})') +#/** +# ogEcho [str_logtype ...] [str_loglevel] "str_message" ... +#@brief Muestra mensajes en consola y lo registra en fichero de incidencias. +#@param str_logtype tipo de registro de incidencias ("log", "command", "session") +#@param str_loglevel nivel de registro de incidencias ("info", "warning", "error") +#@param str_message mensaje (puede recibir más de 1 parámetro. +#@return Mensaje mostrado. +#*/ +def ogEcho (logtypes, loglevel, msg): + logfiles = ['/dev/stdout'] + if type (logtypes) is list: + for l in logtypes: + logfiles.append (_logtype2logfile (l)) + else: ## string + logfiles.append (_logtype2logfile (logtypes)) + + if loglevel is None or 'help' == loglevel: + if ogGlobals.DEBUG.lower() != "no": + logfiles.append (ogGlobals.OGLOGFILE) + for f in logfiles: + with open (f, 'a') as fd: + fd.write (msg + '\n') + return + + if 'info' == loglevel or 'warning' == loglevel or 'error' == loglevel: + DATETIME = datetime.datetime.now(ZoneInfo(ogGlobals.TZ)).strftime("%F %T %Z") + + for f in logfiles: + with open (f, 'a') as fd: + fd.write (f"OpenGnsys {loglevel} {DATETIME} {msg}\n") + else: + raise Exception (f'unknown loglevel ({loglevel})') + + +#/** +# ogExecAndLog str_logfile ... str_command ... +#@brief Ejecuta un comando y guarda su salida en fichero de registro. +#@param str_logfile fichero de registro (pueden ser varios). +#@param str_command comando y comandos a ejecutar. +#@return Salida de ejecución del comando. +#@note str_logfile = { LOG, SESSION, COMMAND } +#*/ +#ogHelp (str_logfile ... str_command ...", +#ogHelp ([], ogMyLib.ogSomeMethod, *args, **kwargs) +#ogHelp ('command', ogMyLib.ogSomeMethod, *args, **kwargs) +#ogHelp (['command'], ogMyLib.ogSomeMethod, *args, **kwargs) +#ogHelp (['log', 'command'], ogMyLib.ogSomeMethod, *args, **kwargs) +def ogExecAndLog (logtypes, fun, *args, **kwargs): + logfiles = ['/dev/stdout'] + if type (logtypes) is list: + for l in logtypes: + logtypes = list (map (lambda x: x.lower(), logtypes)) + logfiles.append (_logtype2logfile (l)) + else: ## string + logtypes = logtypes.lower() + logfiles.append (_logtype2logfile (logtypes)) + + if not fun: + ogRaiseError ([], ogGlobals.OG_ERR_FORMAT, 'no function provided') + return + + ## the original bash code does something like this: + #if [ $ISCOMMAND ]; then + # > $OGLOGCOMMAND + # REDIREC="2>&1" + #fi + #eval $COMMAND $REDIREC | tee -a $FILES + + ## a hybrid bash/python pseudocode would end up being like the following: + #if 'command' in logtypes: + # rm $OGLOGCOMMAND + # touch $OGLOGCOMMAND + # + #if 'command' in logtypes: + # ## redirect both stdout and stderr + # eval $COMMAND 2>&1 | tee -a $FILES + #else: + # ## redirect stdout only + # eval $COMMAND | tee -a $FILES + + import time + sout = serr = '' + if 'command' in logtypes: + os.unlink (ogGlobals.OGLOGCOMMAND) + open (ogGlobals.OGLOGCOMMAND, 'w').close() + #print ('nati: ogExecAndLog: about to redirect stdout and stderr') + #time.sleep (1) ## nati + with redirect_stdout (StringIO()) as r_stdout, redirect_stderr (StringIO()) as r_stderr: + rc = fun (*args, **kwargs) + sout = r_stdout.getvalue() + serr = r_stderr.getvalue() + #print (f'nati: ogExecAndLog: end of redirections, rc ({rc}) sout ({sout}) serr ({serr})') + #time.sleep (1) ## nati + else: + #print ('nati: ogExecAndLog: about to redirect stdout only') + #time.sleep (1) ## nati + with redirect_stdout (StringIO()) as r_stdout: + rc = fun (*args, **kwargs) + sout = r_stdout.getvalue() + #print (f'nati: ogExecAndLog: end of redirections, rc ({rc}) sout ({sout})') + #time.sleep (1) ## nati + + rc_str = str (rc) + if sout or serr or ('True' != rc_str and 'False' != rc_str and 'None' != rc_str): + #print ('nati: ogExecAndLog: sout or serr are true') + #time.sleep (1) ## nati + for f in logfiles: + #print (f'nati: ogExecAndLog: logging to logfile ({f})') + with open (f, 'a') as fd: + if sout: fd.write (f'{sout}\n') + if serr: fd.write (f'{serr}\n') + if rc_str: fd.write (f'{rc_str}\n') + #fd.write (f"ogExecAndLog: {fun.__name__} rc:\n{rc_str}\n") + #if sout: fd.write (f"ogExecAndLog: {fun.__name__} stdout:\n{sout}\n") + #else: fd.write (f"ogExecAndLog: {fun.__name__} stdout: (none)\n") + #if serr: fd.write (f"ogExecAndLog: {fun.__name__} stderr:\n{serr}\n") + #else: fd.write (f"ogExecAndLog: {fun.__name__} stderr: (none)\n") + + #print (f'nati: ogExecAndLog: returning rc ({rc})') + return rc + +#/** +# ogGetCaller +#@brief Devuelve nombre del programa o script ejecutor (padre). +#@return str_name - Nombre del programa ejecutor. +#*/ +def ogGetCaller(): + if 'COLUMNS' in os.environ: + cols = os.environ['COLUMNS'] + else: + cols = None + + lines = subprocess.run (["ps", "hp", str(os.getppid()), "-o", "args"], capture_output=True, text=True).stdout.splitlines() + if 0 == len (lines): + return '' + + line = lines[0] + words = line.split() + if "bash" in line and len(words)>1: + caller = words[1] + else: + caller = words[0].lstrip("-") + + if cols is None: + del (os.environ['COLUMNS']) + else: + os.environ['COLUMNS'] = cols + + return os.path.basename(caller) + +#/** +# ogHelp ["str_function" ["str_format" ["str_example" ... ]]] +#@brief Muestra mensaje de ayuda para una función determinda. +#@param str_function Nombre de la función. +#@param str_format Formato de ejecución de la función. +#@param str_example Ejemplo de ejecución de la función. +#@return str_help - Salida de ayuda. +#@note Si no se indican parámetros, la función se toma de la variable \c $FUNCNAME +#@note La descripción de la función se toma de la variable compuesta por \c MSG_FUNC_$función incluida en el fichero de idiomas. +#@note Pueden especificarse varios mensajes con ejemplos. +#*/ +def ogHelp (fname, fmt=None, examples=[]): + FUNC = fname or inspect.stack()[1][3] + MSG = f'ogGlobals.lang.MSG_HELP_{FUNC}' + try: + MSG = eval (MSG) + except: + MSG = '' + ogEcho ([], "help", f"{ogGlobals.lang.MSG_FUNCTION} {FUNC}: {MSG}") + if fmt: + ogEcho([], "help", f" {ogGlobals.lang.MSG_FORMAT}: {fmt}") + + if type (examples) is list: + for example in examples: + ogEcho([], "help", f" {ogGlobals.lang.MSG_EXAMPLE}: {example}") + else: ## string + ogEcho([], "help", f" {ogGlobals.lang.MSG_EXAMPLE}: {examples}") + +#/** +# ogRaiseError [str_logtype ...] int_errcode ["str_errmessage" ...] +#@brief Devuelve el mensaje y el código de error correspondiente. +#@param str_logtype tipo de registro de incidencias. +#@param int_errcode código de error. +#@param str_errmessage mensajes complementarios de error. +#@return str_code - código de error +#*/ +def ogRaiseError (logtypes, code, msg): + if code == ogGlobals.OG_ERR_FORMAT: MSG = f'{ogGlobals.lang.MSG_ERR_FORMAT} "{msg}"' + elif code == ogGlobals.OG_ERR_NOTFOUND: MSG = f'{ogGlobals.lang.MSG_ERR_NOTFOUND} "{msg}"' + elif code == ogGlobals.OG_ERR_OUTOFLIMIT: MSG = f'{ogGlobals.lang.MSG_ERR_OUTOFLIMIT} "{msg}"' + elif code == ogGlobals.OG_ERR_PARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_PARTITION} "{msg}"' + elif code == ogGlobals.OG_ERR_LOCKED: MSG = f'{ogGlobals.lang.MSG_ERR_LOCKED} "{msg}"' + elif code == ogGlobals.OG_ERR_CACHE: MSG = f'{ogGlobals.lang.MSG_ERR_CACHE} "{msg}"' + elif code == ogGlobals.OG_ERR_NOGPT: MSG = f'{ogGlobals.lang.MSG_ERR_NOGPT} "{msg}"' + elif code == ogGlobals.OG_ERR_REPO: MSG = f'{ogGlobals.lang.MSG_ERR_REPO} "{msg}"' + elif code == ogGlobals.OG_ERR_FILESYS: MSG = f'{ogGlobals.lang.MSG_ERR_FILESYS} "{msg}"' + elif code == ogGlobals.OG_ERR_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_IMAGE} "{msg}"' + elif code == ogGlobals.OG_ERR_NOTOS: MSG = f'{ogGlobals.lang.MSG_ERR_NOTOS} "{msg}"' + elif code == ogGlobals.OG_ERR_NOTEXEC: MSG = f'{ogGlobals.lang.MSG_ERR_NOTEXEC} "{msg}"' + elif code == ogGlobals.OG_ERR_NOTWRITE: MSG = f'{ogGlobals.lang.MSG_ERR_NOTWRITE} "{msg}"' + elif code == ogGlobals.OG_ERR_NOTCACHE: MSG = f'{ogGlobals.lang.MSG_ERR_NOTCACHE} "{msg}"' + elif code == ogGlobals.OG_ERR_CACHESIZE: MSG = f'{ogGlobals.lang.MSG_ERR_CACHESIZE} "{msg}"' + elif code == ogGlobals.OG_ERR_REDUCEFS: MSG = f'{ogGlobals.lang.MSG_ERR_REDUCEFS} "{msg}"' + elif code == ogGlobals.OG_ERR_EXTENDFS: MSG = f'{ogGlobals.lang.MSG_ERR_EXTENDFS} "{msg}"' + elif code == ogGlobals.OG_ERR_IMGSIZEPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_IMGSIZEPARTITION} "{msg}"' + elif code == ogGlobals.OG_ERR_UPDATECACHE: MSG = f'{ogGlobals.lang.MSG_ERR_UPDATECACHE} "{msg}"' + elif code == ogGlobals.OG_ERR_DONTFORMAT: MSG = f'{ogGlobals.lang.MSG_ERR_DONTFORMAT} "{msg}"' + elif code == ogGlobals.OG_ERR_IMAGEFILE: MSG = f'{ogGlobals.lang.MSG_ERR_IMAGEFILE} "{msg}"' + elif code == ogGlobals.OG_ERR_UCASTSYNTAXT: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTSYNTAXT} "{msg}"' + elif code == ogGlobals.OG_ERR_UCASTSENDPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTSENDPARTITION} "{msg}"' + elif code == ogGlobals.OG_ERR_UCASTSENDFILE: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTSENDFILE} "{msg}"' + elif code == ogGlobals.OG_ERR_UCASTRECEIVERPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTRECEIVERPARTITION} "{msg}"' + elif code == ogGlobals.OG_ERR_UCASTRECEIVERFILE: MSG = f'{ogGlobals.lang.MSG_ERR_UCASTRECEIVERFILE} "{msg}"' + elif code == ogGlobals.OG_ERR_MCASTSYNTAXT: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTSYNTAXT} "{msg}"' + elif code == ogGlobals.OG_ERR_MCASTSENDFILE: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTSENDFILE} "{msg}"' + elif code == ogGlobals.OG_ERR_MCASTRECEIVERFILE: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTRECEIVERFILE} "{msg}"' + elif code == ogGlobals.OG_ERR_MCASTSENDPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTSENDPARTITION} "{msg}"' + elif code == ogGlobals.OG_ERR_MCASTRECEIVERPARTITION: MSG = f'{ogGlobals.lang.MSG_ERR_MCASTRECEIVERPARTITION} "{msg}"' + elif code == ogGlobals.OG_ERR_PROTOCOLJOINMASTER: MSG = f'{ogGlobals.lang.MSG_ERR_PROTOCOLJOINMASTER} "{msg}"' + elif code == ogGlobals.OG_ERR_DONTMOUNT_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_DONTMOUNT_IMAGE} "{msg}"' + elif code == ogGlobals.OG_ERR_DONTUNMOUNT_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_DONTUNMOUNT_IMAGE} "{msg}"' + elif code == ogGlobals.OG_ERR_DONTSYNC_IMAGE: MSG = f'{ogGlobals.lang.MSG_ERR_DONTSYNC_IMAGE} "{msg}"' + elif code == ogGlobals.OG_ERR_NOTDIFFERENT: MSG = f'{ogGlobals.lang.MSG_ERR_NOTDIFFERENT} "{msg}"' + elif code == ogGlobals.OG_ERR_SYNCHRONIZING: MSG = f'{ogGlobals.lang.MSG_ERR_SYNCHRONIZING} "{msg}"' + elif code == ogGlobals.OG_ERR_NOTUEFI: MSG = f'{ogGlobals.lang.MSG_ERR_NOTUEFI} "{msg}"' + elif code == ogGlobals.OG_ERR_NOMSDOS: MSG = f'{ogGlobals.lang.MSG_ERR_NOMSDOS} "{msg}"' + elif code == ogGlobals.OG_ERR_NOTBIOS: MSG = f'{ogGlobals.lang.MSG_ERR_NOTBIOS} "{msg}"' + else: + MSG = ogGlobals.lang.MSG_ERR_GENERIC + CODE = ogGlobals.OG_ERR_GENERIC + + # Obtener lista de funciones afectadas, incluyendo el script que las llama. + call_stack = [i[3] for i in inspect.stack()] + if len (call_stack) < 2: return ## shouldn't happen + call_stack.pop() ## remove '' + call_stack.pop(0) ## remove 'ogRaiseError' + str_call_stack = ' '.join (call_stack) + + # Mostrar mensaje de error si es función depurable y salir con el código indicado. + if code == ogGlobals.OG_ERR_FORMAT or \ + (str_call_stack in ogGlobals.NODEBUGFUNCTIONS) or \ + not (len(call_stack)>0 and (call_stack[0] in ogGlobals.NODEBUGFUNCTIONS)): + #print ('nati: ogRaiseError: actually calling ogEcho') + ogEcho (logtypes, "error", f"{str_call_stack.replace(' ', '<-')}: {MSG}") + + return code + +#/** +# ogIsRepoLocked +#@brief Comprueba si el repositorio está siendo usado (tiene ficheros abiertos). +#@param No. +#@return Código de salida: 0 - bloqueado, 1 - sin bloquear o error. +#*/ +def ogIsRepoLocked(): +# No hacer nada, si no está definido el punto de montaje del repositorio. + if not ogGlobals.OGIMG: + return False + +# Comprobar si alguno de los ficheros abiertos por los procesos activos está en el +# punto de montaje del repositorio de imágenes. + proc_entries = glob.glob ('/proc/[0-9]*/fd/*') + for e in proc_entries: + p = os.path.realpath (e) + if ogGlobals.OGIMG in p: + return True + return False + +## has no users +#def ogCheckProgram(program): +# FUNCNAME = ogCheckProgram.__name__ +# +# if not program or not isinstance(program, str): +# SystemLib.ogRaiseError ("session", ogGlobals.OG_ERR_FORMAT, f"Error: {ogGlobals.lang.MSG_ERR_FORMAT} {FUNCNAME} \"program\"") +# return +# +# if not shutil.which(program): +# SystemLib.ogRaiseError ( "session", ogGlobals.OG_ERR_NOTEXEC, f"Error: The program '{program}' is not available on the system.") +# return +# +# return 0 + +def ogIsVirtualMachine(): + output = subprocess.run (["dmidecode", "-s", "system-product-name"], capture_output=True, text=True).stdout + return "KVM" in output or "VirtualBox" in output diff --git a/client/lib/python3/ogGlobals.py b/client/lib/python3/ogGlobals.py new file mode 100644 index 0000000..29eea03 --- /dev/null +++ b/client/lib/python3/ogGlobals.py @@ -0,0 +1,145 @@ +#!/usr/bin/python3 + +import sys +import os +import os.path +import locale +import importlib.util + +def load_lang (name): + global lang + if name in sys.modules: + return True + elif (spec := importlib.util.find_spec (name)) is not None: + lang = importlib.util.module_from_spec (spec) + sys.modules[name] = lang + spec.loader.exec_module (lang) + return True + else: + #print(f"can't find the {name!r} module") + return False + +l = locale.getlocale()[0] +if not l: print (f"couldn't set locale") +if not l or not load_lang (f'lang_{l}'): + if not load_lang ('lang_en_GB'): + raise ModuleNotFoundError (f"can't find the default language module", name=name) + +TZ='Europe/Madrid' + + +## engine.cfg +OGLOGSESSION='/tmp/session.log' +OGLOGCOMMAND='/tmp/command.log' +#OGWINCHKDISK=True #Hacer chkdisk tras la clonacion +ACTIONCACHEFULL='NONE' #Que hacer cuando la cache no tenga espacio libre. [ NONE | FORMAT ] ] +RESTOREPROTOCOLNOTCACHE=None #Que protocolo de restauracion usar en el caso de que no exista cache o no exista espacio sufiente. [NONE | UNICAST | MULTICAST].NONE retorna error +IMGPROG='partclone' +IMGCOMP='lzop' +IMGEXT='img' +IMGREDUCE=True +#OGWINREDUCE=True #Al enviar particion reducir el sistema de archivos previamente. +MCASTERRORSESSION=120 #timeout (segundos) para abortar la sesion de multicast si no contacta con el servidor de multicast. Valor asignado a 0, utiliza los valores por defecto de udp-cast +MCASTWAIT=30 # timeout (segundos) para abortar la la transferencia si se interrumpe. Valor asignado a 0, utiliza los valores por defecto de udp-cast +#CREATESPEED=100000*4 # Factor para calcular el time-out al crear la imagen. 100000k -> 4s +#FACTORSYNC=120 # Factor de compresion para las imagenes (windos en ext4). +#BACKUP=False # Realizar copia de seguridad antes de crear la imagen. +#IMGFS='EXT4' # Sistema de archivo de la imagenes sincronizadas. EXT4 o BTRFS +#OGSLEEP=20 # Tiempo de sleep antes de realizar el reboot +NODEBUGFUNCTIONS=['ogCreateImageSyntax', 'ogGetHivePath', 'ogGetOsType', 'ogRestoreImageSyntax', 'ogUnmountAll', 'ogUnmountCache'] # Funciones que no deben mostrar salida de avisos si son llamadas por otras funciones. +#DEFAULTSPEED='' +## /engine.cfg + + +## loadenviron.sh +OPENGNSYS = '/opt/opengnsys' +OGBIN = os.path.join (OPENGNSYS, 'bin') +OGETC = os.path.join (OPENGNSYS, 'etc') +OGLIB = os.path.join (OPENGNSYS, 'lib') +OGAPI = os.path.join (OGLIB, 'engine', 'bin') +OGSCRIPTS = os.path.join (OPENGNSYS, 'scripts') +OGIMG = os.path.join (OPENGNSYS, 'images') +OGCAC = os.path.join (OPENGNSYS, 'cache') +OGLOG = os.path.join (OPENGNSYS, 'log') +OGLOGFILE = f'{OGLOG}/192.168.42.42' ## TODO import NetLib; OGLOGFILE = f'$OGLOG/{NetLib.ogGetIpAddress()}.log' +DEBUG = 'yes' +_path = os.environ['PATH'] + ':/sbin:/usr/sbin:/usr/local/sbin:/bin:/usr/bin:/usr/local/bin:/opt/oglive/rootfs/opt/drbl/sbin' +os.environ['PATH'] = ':'.join ([OGSCRIPTS, _path, OGAPI, OGBIN]) + +if os.path.exists ('/tmp/initrd.cfg'): + with open ('/tmp/initrd.cfg', 'r') as fd: + initrd_cfg = fd.read() + for l in initrd_cfg.splitlines(): + if not l.startswith ('DEVICECFG='): continue ## eg. "DEVICECFG=/run/net-enp0s3.conf" + device_cfg = l.split ('=')[1] + if os.path.exists (device_cfg): + with open (device_cfg, 'r') as fd: + contents = fd.read() + exec (contents) ## !!! + ## example contents: + #DEVICE='enp0s3' + #PROTO='none' + #IPV4ADDR='192.168.2.11' + #IPV4BROADCAST='192.168.2.255' + #IPV4NETMASK='255.255.255.0' + #IPV4GATEWAY='192.168.2.1' + #IPV4DNS0='0.0.0.0' + #IPV4DNS1='0.0.0.0' + #HOSTNAME='pc1' + #DNSDOMAIN='' + #NISDOMAIN='' + #ROOTSERVER='10.0.2.15' + #ROOTPATH='' + #filename='' + #UPTIME='161' + #DHCPLEASETIME='0' + #DOMAINSEARCH='' + break +## /loadenviron.sh + +# Declaración de códigos de error. +OG_ERR_FORMAT=1 # Formato de ejecución incorrecto. +OG_ERR_NOTFOUND=2 # Fichero o dispositivo no encontrado. +OG_ERR_PARTITION=3 # Error en partición de disco. +OG_ERR_LOCKED=4 # Partición o fichero bloqueado. +OG_ERR_IMAGE=5 # Error al crear o restaurar una imagen. +OG_ERR_NOTOS=6 # Sin sistema operativo. +OG_ERR_NOTEXEC=7 # Programa o función no ejecutable. +# Códigos 8-13 reservados por ogAdmClient.h +OG_ERR_NOTWRITE=14 # No hay acceso de escritura +OG_ERR_NOTCACHE=15 # No hay particion cache en cliente +OG_ERR_CACHESIZE=16 # No hay espacio en la cache para almacenar fichero-imagen +OG_ERR_REDUCEFS=17 # Error al reducir sistema archivos +OG_ERR_EXTENDFS=18 # Error al expandir el sistema de archivos +OG_ERR_OUTOFLIMIT=19 # Valor fuera de rango o no válido. +OG_ERR_FILESYS=20 # Sistema de archivos desconocido o no se puede montar +OG_ERR_CACHE=21 # Error en partición de caché local +OG_ERR_NOGPT=22 # El disco indicado no contiene una particion GPT +OG_ERR_REPO=23 # Error al montar el repositorio de imagenes +OG_ERR_NOMSDOS=24 # El disco indicado no contienen una particion MSDOS + +OG_ERR_IMGSIZEPARTITION=30 # Error al restaurar partición más pequeña que la imagen +OG_ERR_UPDATECACHE=31 # Error al realizar el comando updateCache +OG_ERR_DONTFORMAT=32 # Error al formatear +OG_ERR_IMAGEFILE=33 # Archivo de imagen corrupto o de otra versión de $IMGPROG +OG_ERR_GENERIC=40 # Error imprevisto no definido +OG_ERR_UCASTSYNTAXT=50 # Error en la generación de sintaxis de transferenica UNICAST +OG_ERR_UCASTSENDPARTITION=51 # Error en envío UNICAST de partición +OG_ERR_UCASTSENDFILE=52 # Error en envío UNICAST de un fichero +OG_ERR_UCASTRECEIVERPARTITION=53 # Error en la recepcion UNICAST de una particion +OG_ERR_UCASTRECEIVERFILE=54 # Error en la recepcion UNICAST de un fichero +OG_ERR_MCASTSYNTAXT=55 # Error en la generacion de sintaxis de transferenica Multicast. +OG_ERR_MCASTSENDFILE=56 # Error en envio MULTICAST de un fichero +OG_ERR_MCASTRECEIVERFILE=57 # Error en la recepcion MULTICAST de un fichero +OG_ERR_MCASTSENDPARTITION=58 # Error en envio MULTICAST de una particion +OG_ERR_MCASTRECEIVERPARTITION=59 # Error en la recepcion MULTICAST de una particion +OG_ERR_PROTOCOLJOINMASTER=60 # Error en la conexion de una sesion UNICAST|MULTICAST con el MASTER + +OG_ERR_DONTMOUNT_IMAGE=70 # Error al montar una imagen sincronizada. +OG_ERR_DONTSYNC_IMAGE=71 # Imagen no sincronizable (es monolitica) +OG_ERR_DONTUNMOUNT_IMAGE=72 # Error al desmontar la imagen +OG_ERR_NOTDIFFERENT=73 # No se detectan diferencias entre la imagen basica y la particion. +OG_ERR_SYNCHRONIZING=74 # Error al sincronizar, puede afectar la creacion/restauracion de la imagen + +OG_ERR_NOTUEFI=80 # La interfaz UEFI no está activa +OG_ERR_NOTBIOS=81 # La interfaz BIOS legacy no está activa