source: ogClient-Git/src/utils/probe.py

Last change on this file was 4e5b17c, checked in by Jose M. Guisado <jguisado@…>, 3 years ago

probe: detect 64 bit operating systems

OpenGnsys partition images store OS information, including
the OS name appended with "64 bits" when the OS is meant for 64 bit
machines.

The detected OS name when probing (refresh) is important, if it differs
from what's stored in the DB OpenGnsys will wipe last image restored
information when running a refresh.

See actualizaConfiguracion from legacy ogserver (ogAdmServer.c) code:

dato = dbi_result_get_uint(result, "idnombreso");
if (idsoi == dato) {

swu = false;

}
...
if (swu) {

result_update = dbi_conn_queryf(dbi->conn,
"UPDATE ordenadores_particiones SET "

" codpar=0x%s,"
" tamano=%s,"
" uso=%s,"
" idsistemafichero=%d,"
" idnombreso=%d,"
" idimagen=0,"
" idperfilsoft=0,"
" fechadespliegue=NULL"
" WHERE idordenador=%d AND numdisk=%s AND numpar=%s",

  • Property mode set to 100644
File size: 4.2 KB
Line 
1#
2# Copyright (C) 2022 Soleta Networks <info@soleta.eu>
3#
4# This program is free software: you can redistribute it and/or modify it under
5# the terms of the GNU Affero General Public License as published by the
6# Free Software Foundation; either version 3 of the License, or
7# (at your option) any later version.
8
9import os
10import subprocess
11import platform
12
13from subprocess import PIPE
14
15from src.utils.fs import find_mountpoint
16
17def getlinuxversion(osrelease):
18    """
19    Parses a os-release file to fetch 'PRETTY_NAME' key.
20    If file or key are not found, then returns generic
21    'Linux' string.
22    """
23    mountpoint = find_mountpoint(osrelease)
24
25    with open(osrelease, 'r') as f:
26        for line in f:
27            if line.find('=') == -1:
28                continue
29            key, value = line.split('=')
30            if key == 'PRETTY_NAME':
31                value = value.replace('\n', '')
32                value = value.strip('"')
33                bits = ' 64 bits' if linux_is64bit(mountpoint) else ''
34                return f'{value}{bits}'
35        return 'Linux'
36
37
38def getwindowsversion(winreghives):
39    """
40    Tries to obtain windows version information by
41    querying the SOFTWARE registry hive. Registry
42    hives path is a required parameter.
43
44    Runs hivexget(1) to fetch ProductName and
45    ReleaseId. If something fails (hivexget is
46    not installed, or registry is not found) it
47    returns a generic "Microsoft Windows" string.
48    """
49
50    # XXX: 3.6 friendly
51    try:
52        proc_prodname = subprocess.run(['hivexget',
53            f'{winreghives}/SOFTWARE',
54            'microsoft\windows nt\currentversion',
55            'ProductName'], stdout=PIPE)
56        proc_releaseid = subprocess.run(['hivexget',
57            f'{winreghives}/SOFTWARE',
58            'microsoft\windows nt\currentversion',
59            'ReleaseId'], stdout=PIPE)
60
61        prodname = proc_prodname.stdout.decode().replace('\n', '')
62        releaseid = proc_releaseid.stdout.decode().replace('\n', '')
63        bits = ' 64 bits' if windows_is64bit(winreghives) else ''
64
65        if proc_prodname.returncode == 0 and proc_releaseid.returncode == 0:
66            return f'{prodname} {releaseid}{bits}'
67    except FileNotFoundError:  # hivexget command not found
68        pass
69    return 'Microsoft Windows'
70
71
72def windows_is64bit(winreghives):
73    """
74    Check for 64 bit Windows by means of retrieving the value of
75    ProgramW6432Dir. This key is set if Windows is running 64 bit.
76
77    If set returns True.
78    If not set or hivexget exits with non-zero, returns False.
79    """
80    try:
81        proc_hivexget = subprocess.run(['hivexget',
82            f'{winreghives}/SOFTWARE',
83            'Microsoft\Windows\CurrentVersion',
84            'ProgramW6432Dir'], stdout=PIPE)
85        stdout = proc_hivexget.stdout.decode().replace('\n', '')
86
87        if proc_hivexget.returncode == 0 and stdout:
88            return True
89    except FileNotFoundError:  # hivexget command not found
90        pass
91    return False
92
93
94def linux_is64bit(mountpoint):
95    """
96    If /sbin/init is detected, check if compiled for 64-bit machine.
97
98    If init executable is not found, check for /lib64.
99    If /lib64 is found returns True, otherwise False.
100    """
101    init_path = f'{mountpoint}/sbin/init'
102    lib64_path = f'{mountpoint}/lib64'
103    if os.path.exists(init_path):
104        bits, linkage = platform.architecture(executable=init_path)
105        return True if bits == '64bit' else False
106    return os.path.exists(lib64_path)
107
108
109def cache_probe():
110    """
111    Runs 'blkid -L CACHE' and returns stripped stdout
112    """
113    proc_blkid = subprocess.run(['blkid', '-L', 'CACHE'],
114                                stdout=subprocess.PIPE)
115    stdout = proc_blkid.stdout.decode().strip()
116    return stdout
117
118def os_probe(mountpoint):
119    """
120    Probes mountpoint for typical OS dependant files.
121
122    Windows: Tries finding and querying the software
123    registry hive.
124    Linux: Looks for /etc/os-release file.
125
126    Returns a string depending on the OS it detects.
127    """
128    winreghives = f'{mountpoint}/Windows/System32/config'
129    osrelease = f'{mountpoint}/etc/os-release'
130
131    if os.path.exists(osrelease):
132        return getlinuxversion(osrelease)
133    elif os.path.exists(winreghives):
134        return getwindowsversion(winreghives)
135    else:
136        return ''
Note: See TracBrowser for help on using the repository browser.