Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
commit
9c34c08699
24 changed files with 2353 additions and 2475 deletions
|
|
@ -1,35 +0,0 @@
|
||||||
sensors.py
|
|
||||||
==========
|
|
||||||
python bindings using ctypes for libsensors3 of the [lm-sensors project](https://github.com/groeck/lm-sensors). The code was written against libsensors 3.3.4.
|
|
||||||
|
|
||||||
For documentation of the low level API see [sensors.h](https://github.com/groeck/lm-sensors/blob/master/lib/sensors.h). For an example of the high level API see [example.py](example.py).
|
|
||||||
|
|
||||||
For a GUI application that displays the sensor readings and is based on this library, take a look at [sensors-unity](https://launchpad.net/sensors-unity).
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
* Full access to low level libsensors3 API
|
|
||||||
* High level iterator API
|
|
||||||
* unicode handling
|
|
||||||
* Python2 and Python3 compatible
|
|
||||||
|
|
||||||
Licensing
|
|
||||||
---------
|
|
||||||
LGPLv2 (same as libsensors3)
|
|
||||||
|
|
||||||
Usage Notes
|
|
||||||
-----------
|
|
||||||
As Python does not support call by reference for primitive types some of the libsensors API had to be adapted:
|
|
||||||
|
|
||||||
```python
|
|
||||||
# nr is changed by refrence in the C API
|
|
||||||
chip_name, nr = sensors.get_detected_chips(None, nr)
|
|
||||||
|
|
||||||
# returns the value. throws on error
|
|
||||||
val = sensors.get_value(chip, subfeature_nr)
|
|
||||||
```
|
|
||||||
|
|
||||||
Missing Features (pull requests are welcome):
|
|
||||||
* `sensors_subfeature_type` enum
|
|
||||||
* `sensors_get_subfeature`
|
|
||||||
* Error handlers
|
|
||||||
|
|
@ -1,236 +0,0 @@
|
||||||
"""
|
|
||||||
@package sensors.py
|
|
||||||
Python Bindings for libsensors3
|
|
||||||
|
|
||||||
use the documentation of libsensors for the low level API.
|
|
||||||
see example.py for high level API usage.
|
|
||||||
|
|
||||||
@author: Pavel Rojtberg (http://www.rojtberg.net)
|
|
||||||
@see: https://github.com/paroj/sensors.py
|
|
||||||
@copyright: LGPLv2 (same as libsensors) <http://opensource.org/licenses/LGPL-2.1>
|
|
||||||
"""
|
|
||||||
|
|
||||||
from ctypes import *
|
|
||||||
import ctypes.util
|
|
||||||
|
|
||||||
_libc = cdll.LoadLibrary(ctypes.util.find_library("c"))
|
|
||||||
# see https://github.com/paroj/sensors.py/issues/1
|
|
||||||
_libc.free.argtypes = [c_void_p]
|
|
||||||
|
|
||||||
_hdl = cdll.LoadLibrary(ctypes.util.find_library("sensors"))
|
|
||||||
|
|
||||||
version = c_char_p.in_dll(_hdl, "libsensors_version").value.decode("ascii")
|
|
||||||
|
|
||||||
class bus_id(Structure):
|
|
||||||
_fields_ = [("type", c_short),
|
|
||||||
("nr", c_short)]
|
|
||||||
|
|
||||||
class chip_name(Structure):
|
|
||||||
_fields_ = [("prefix", c_char_p),
|
|
||||||
("bus", bus_id),
|
|
||||||
("addr", c_int),
|
|
||||||
("path", c_char_p)]
|
|
||||||
|
|
||||||
class feature(Structure):
|
|
||||||
_fields_ = [("name", c_char_p),
|
|
||||||
("number", c_int),
|
|
||||||
("type", c_int)]
|
|
||||||
|
|
||||||
# sensors_feature_type
|
|
||||||
IN = 0x00
|
|
||||||
FAN = 0x01
|
|
||||||
TEMP = 0x02
|
|
||||||
POWER = 0x03
|
|
||||||
ENERGY = 0x04
|
|
||||||
CURR = 0x05
|
|
||||||
HUMIDITY = 0x06
|
|
||||||
MAX_MAIN = 0x7
|
|
||||||
VID = 0x10
|
|
||||||
INTRUSION = 0x11
|
|
||||||
MAX_OTHER = 0x12
|
|
||||||
BEEP_ENABLE = 0x18
|
|
||||||
|
|
||||||
class subfeature(Structure):
|
|
||||||
_fields_ = [("name", c_char_p),
|
|
||||||
("number", c_int),
|
|
||||||
("type", c_int),
|
|
||||||
("mapping", c_int),
|
|
||||||
("flags", c_uint)]
|
|
||||||
|
|
||||||
_hdl.sensors_get_detected_chips.restype = POINTER(chip_name)
|
|
||||||
_hdl.sensors_get_features.restype = POINTER(feature)
|
|
||||||
_hdl.sensors_get_all_subfeatures.restype = POINTER(subfeature)
|
|
||||||
_hdl.sensors_get_label.restype = c_void_p # return pointer instead of str so we can free it
|
|
||||||
_hdl.sensors_get_adapter_name.restype = c_char_p # docs do not say whether to free this or not
|
|
||||||
_hdl.sensors_strerror.restype = c_char_p
|
|
||||||
|
|
||||||
### RAW API ###
|
|
||||||
MODE_R = 1
|
|
||||||
MODE_W = 2
|
|
||||||
COMPUTE_MAPPING = 4
|
|
||||||
|
|
||||||
def init(cfg_file = None):
|
|
||||||
file = _libc.fopen(cfg_file.encode("utf-8"), "r") if cfg_file is not None else None
|
|
||||||
|
|
||||||
if _hdl.sensors_init(file) != 0:
|
|
||||||
raise Exception("sensors_init failed")
|
|
||||||
|
|
||||||
if file is not None:
|
|
||||||
_libc.fclose(file)
|
|
||||||
|
|
||||||
def cleanup():
|
|
||||||
_hdl.sensors_cleanup()
|
|
||||||
|
|
||||||
def parse_chip_name(orig_name):
|
|
||||||
ret = chip_name()
|
|
||||||
err= _hdl.sensors_parse_chip_name(orig_name.encode("utf-8"), byref(ret))
|
|
||||||
|
|
||||||
if err < 0:
|
|
||||||
raise Exception(strerror(err))
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def strerror(errnum):
|
|
||||||
return _hdl.sensors_strerror(errnum).decode("utf-8")
|
|
||||||
|
|
||||||
def free_chip_name(chip):
|
|
||||||
_hdl.sensors_free_chip_name(byref(chip))
|
|
||||||
|
|
||||||
def get_detected_chips(match, nr):
|
|
||||||
"""
|
|
||||||
@return: (chip, next nr to query)
|
|
||||||
"""
|
|
||||||
_nr = c_int(nr)
|
|
||||||
|
|
||||||
if match is not None:
|
|
||||||
match = byref(match)
|
|
||||||
|
|
||||||
chip = _hdl.sensors_get_detected_chips(match, byref(_nr))
|
|
||||||
chip = chip.contents if bool(chip) else None
|
|
||||||
return chip, _nr.value
|
|
||||||
|
|
||||||
def chip_snprintf_name(chip, buffer_size=200):
|
|
||||||
"""
|
|
||||||
@param buffer_size defaults to the size used in the sensors utility
|
|
||||||
"""
|
|
||||||
ret = create_string_buffer(buffer_size)
|
|
||||||
err = _hdl.sensors_snprintf_chip_name(ret, buffer_size, byref(chip))
|
|
||||||
|
|
||||||
if err < 0:
|
|
||||||
raise Exception(strerror(err))
|
|
||||||
|
|
||||||
return ret.value.decode("utf-8")
|
|
||||||
|
|
||||||
def do_chip_sets(chip):
|
|
||||||
"""
|
|
||||||
@attention this function was not tested
|
|
||||||
"""
|
|
||||||
err = _hdl.sensors_do_chip_sets(byref(chip))
|
|
||||||
if err < 0:
|
|
||||||
raise Exception(strerror(err))
|
|
||||||
|
|
||||||
def get_adapter_name(bus):
|
|
||||||
return _hdl.sensors_get_adapter_name(byref(bus)).decode("utf-8")
|
|
||||||
|
|
||||||
def get_features(chip, nr):
|
|
||||||
"""
|
|
||||||
@return: (feature, next nr to query)
|
|
||||||
"""
|
|
||||||
_nr = c_int(nr)
|
|
||||||
feature = _hdl.sensors_get_features(byref(chip), byref(_nr))
|
|
||||||
feature = feature.contents if bool(feature) else None
|
|
||||||
return feature, _nr.value
|
|
||||||
|
|
||||||
def get_label(chip, feature):
|
|
||||||
ptr = _hdl.sensors_get_label(byref(chip), byref(feature))
|
|
||||||
val = cast(ptr, c_char_p).value.decode("utf-8")
|
|
||||||
_libc.free(ptr)
|
|
||||||
return val
|
|
||||||
|
|
||||||
def get_all_subfeatures(chip, feature, nr):
|
|
||||||
"""
|
|
||||||
@return: (subfeature, next nr to query)
|
|
||||||
"""
|
|
||||||
_nr = c_int(nr)
|
|
||||||
subfeature = _hdl.sensors_get_all_subfeatures(byref(chip), byref(feature), byref(_nr))
|
|
||||||
subfeature = subfeature.contents if bool(subfeature) else None
|
|
||||||
return subfeature, _nr.value
|
|
||||||
|
|
||||||
def get_value(chip, subfeature_nr):
|
|
||||||
val = c_double()
|
|
||||||
err = _hdl.sensors_get_value(byref(chip), subfeature_nr, byref(val))
|
|
||||||
if err < 0:
|
|
||||||
raise Exception(strerror(err))
|
|
||||||
return val.value
|
|
||||||
|
|
||||||
def set_value(chip, subfeature_nr, value):
|
|
||||||
"""
|
|
||||||
@attention this function was not tested
|
|
||||||
"""
|
|
||||||
val = c_double(value)
|
|
||||||
err = _hdl.sensors_set_value(byref(chip), subfeature_nr, byref(val))
|
|
||||||
if err < 0:
|
|
||||||
raise Exception(strerror(err))
|
|
||||||
|
|
||||||
### Convenience API ###
|
|
||||||
class ChipIterator:
|
|
||||||
def __init__(self, match = None):
|
|
||||||
self.match = parse_chip_name(match) if match is not None else None
|
|
||||||
self.nr = 0
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __next__(self):
|
|
||||||
chip, self.nr = get_detected_chips(self.match, self.nr)
|
|
||||||
|
|
||||||
if chip is None:
|
|
||||||
raise StopIteration
|
|
||||||
|
|
||||||
return chip
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if self.match is not None:
|
|
||||||
free_chip_name(self.match)
|
|
||||||
|
|
||||||
def next(self): # python2 compability
|
|
||||||
return self.__next__()
|
|
||||||
|
|
||||||
class FeatureIterator:
|
|
||||||
def __init__(self, chip):
|
|
||||||
self.chip = chip
|
|
||||||
self.nr = 0
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __next__(self):
|
|
||||||
feature, self.nr = get_features(self.chip, self.nr)
|
|
||||||
|
|
||||||
if feature is None:
|
|
||||||
raise StopIteration
|
|
||||||
|
|
||||||
return feature
|
|
||||||
|
|
||||||
def next(self): # python2 compability
|
|
||||||
return self.__next__()
|
|
||||||
|
|
||||||
class SubFeatureIterator:
|
|
||||||
def __init__(self, chip, feature):
|
|
||||||
self.chip = chip
|
|
||||||
self.feature = feature
|
|
||||||
self.nr = 0
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __next__(self):
|
|
||||||
subfeature, self.nr = get_all_subfeatures(self.chip, self.feature, self.nr)
|
|
||||||
|
|
||||||
if subfeature is None:
|
|
||||||
raise StopIteration
|
|
||||||
|
|
||||||
return subfeature
|
|
||||||
|
|
||||||
def next(self): # python2 compability
|
|
||||||
return self.__next__()
|
|
||||||
|
|
@ -533,6 +533,9 @@ echo -e "${GREEN}Building Kit${CLEAR}"
|
||||||
touch "${LOG_FILE}"
|
touch "${LOG_FILE}"
|
||||||
tmux split-window -dl 10 tail -f "${LOG_FILE}"
|
tmux split-window -dl 10 tail -f "${LOG_FILE}"
|
||||||
|
|
||||||
|
# Zero beginning of device
|
||||||
|
dd bs=4M count=16 if=/dev/zero of="${DEST_DEV}" >> "${LOG_FILE}" 2>&1
|
||||||
|
|
||||||
# Format
|
# Format
|
||||||
echo "Formatting drive..."
|
echo "Formatting drive..."
|
||||||
if [[ "${USE_MBR}" == "True" ]]; then
|
if [[ "${USE_MBR}" == "True" ]]; then
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
#!/bin/python3
|
|
||||||
#
|
|
||||||
## Wizard Kit: SMART attributes display for ddrescue TUI
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
|
|
||||||
# Init
|
|
||||||
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
|
||||||
sys.path.append(os.getcwd())
|
|
||||||
from functions.hw_diags import *
|
|
||||||
#init_global_vars()
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
try:
|
|
||||||
# Prep
|
|
||||||
clear_screen()
|
|
||||||
dev_path = sys.argv[1]
|
|
||||||
devs = scan_disks(True, dev_path)
|
|
||||||
|
|
||||||
# Warn if SMART unavailable
|
|
||||||
if dev_path not in devs:
|
|
||||||
print_error('SMART data not available')
|
|
||||||
exit_script()
|
|
||||||
|
|
||||||
# Initial screen
|
|
||||||
dev = devs[dev_path]
|
|
||||||
clear_screen()
|
|
||||||
show_disk_details(dev, only_attributes=True)
|
|
||||||
|
|
||||||
# Done
|
|
||||||
exit_script()
|
|
||||||
except SystemExit:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
major_exception()
|
|
||||||
|
|
||||||
# vim: sts=4 sw=4 ts=4
|
|
||||||
|
|
@ -27,10 +27,12 @@ global_vars = {}
|
||||||
COLORS = {
|
COLORS = {
|
||||||
'CLEAR': '\033[0m',
|
'CLEAR': '\033[0m',
|
||||||
'RED': '\033[31m',
|
'RED': '\033[31m',
|
||||||
|
'ORANGE': '\033[31;1m',
|
||||||
'GREEN': '\033[32m',
|
'GREEN': '\033[32m',
|
||||||
'YELLOW': '\033[33m',
|
'YELLOW': '\033[33m',
|
||||||
'BLUE': '\033[34m'
|
'BLUE': '\033[34m',
|
||||||
}
|
'CYAN': '\033[36m',
|
||||||
|
}
|
||||||
try:
|
try:
|
||||||
HKU = winreg.HKEY_USERS
|
HKU = winreg.HKEY_USERS
|
||||||
HKCR = winreg.HKEY_CLASSES_ROOT
|
HKCR = winreg.HKEY_CLASSES_ROOT
|
||||||
|
|
@ -305,20 +307,20 @@ def major_exception():
|
||||||
except GenericAbort:
|
except GenericAbort:
|
||||||
# User declined upload
|
# User declined upload
|
||||||
print_warning('Upload: Aborted')
|
print_warning('Upload: Aborted')
|
||||||
sleep(30)
|
sleep(10)
|
||||||
except GenericError:
|
except GenericError:
|
||||||
# No log file or uploading disabled
|
# No log file or uploading disabled
|
||||||
sleep(30)
|
sleep(10)
|
||||||
except:
|
except:
|
||||||
print_error('Upload: NS')
|
print_error('Upload: NS')
|
||||||
sleep(30)
|
sleep(10)
|
||||||
else:
|
else:
|
||||||
print_success('Upload: CS')
|
print_success('Upload: CS')
|
||||||
pause('Press Enter to exit...')
|
pause('Press Enter to exit...')
|
||||||
exit_script(1)
|
exit_script(1)
|
||||||
|
|
||||||
def menu_select(title='~ Untitled Menu ~',
|
def menu_select(title='~ Untitled Menu ~',
|
||||||
prompt='Please make a selection', secret_exit=False,
|
prompt='Please make a selection', secret_actions=[], secret_exit=False,
|
||||||
main_entries=[], action_entries=[], disabled_label='DISABLED',
|
main_entries=[], action_entries=[], disabled_label='DISABLED',
|
||||||
spacer=''):
|
spacer=''):
|
||||||
"""Display options in a menu and return selected option as a str."""
|
"""Display options in a menu and return selected option as a str."""
|
||||||
|
|
@ -334,8 +336,10 @@ def menu_select(title='~ Untitled Menu ~',
|
||||||
menu_splash = '{}\n{}\n'.format(title, spacer)
|
menu_splash = '{}\n{}\n'.format(title, spacer)
|
||||||
width = len(str(len(main_entries)))
|
width = len(str(len(main_entries)))
|
||||||
valid_answers = []
|
valid_answers = []
|
||||||
if (secret_exit):
|
if secret_exit:
|
||||||
valid_answers.append('Q')
|
valid_answers.append('Q')
|
||||||
|
if secret_actions:
|
||||||
|
valid_answers.extend(secret_actions)
|
||||||
|
|
||||||
# Add main entries
|
# Add main entries
|
||||||
for i in range(len(main_entries)):
|
for i in range(len(main_entries)):
|
||||||
|
|
@ -367,7 +371,6 @@ def menu_select(title='~ Untitled Menu ~',
|
||||||
letter = entry['Letter'].upper(),
|
letter = entry['Letter'].upper(),
|
||||||
width = len(str(len(action_entries))),
|
width = len(str(len(action_entries))),
|
||||||
name = entry['Name'])
|
name = entry['Name'])
|
||||||
menu_splash += '\n'
|
|
||||||
|
|
||||||
answer = ''
|
answer = ''
|
||||||
|
|
||||||
|
|
@ -403,19 +406,24 @@ def ping(addr='google.com'):
|
||||||
|
|
||||||
def popen_program(cmd, pipe=False, minimized=False, shell=False, **kwargs):
|
def popen_program(cmd, pipe=False, minimized=False, shell=False, **kwargs):
|
||||||
"""Run program and return a subprocess.Popen object."""
|
"""Run program and return a subprocess.Popen object."""
|
||||||
startupinfo=None
|
cmd_kwargs = {'args': cmd, 'shell': shell}
|
||||||
|
|
||||||
if minimized:
|
if minimized:
|
||||||
startupinfo = subprocess.STARTUPINFO()
|
startupinfo = subprocess.STARTUPINFO()
|
||||||
startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW
|
startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW
|
||||||
startupinfo.wShowWindow = 6
|
startupinfo.wShowWindow = 6
|
||||||
|
cmd_kwargs['startupinfo'] = startupinfo
|
||||||
|
|
||||||
if pipe:
|
if pipe:
|
||||||
popen_obj = subprocess.Popen(cmd, shell=shell, startupinfo=startupinfo,
|
cmd_kwargs.update({
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
'stdout': subprocess.PIPE,
|
||||||
else:
|
'stderr': subprocess.PIPE,
|
||||||
popen_obj = subprocess.Popen(cmd, shell=shell, startupinfo=startupinfo)
|
})
|
||||||
|
|
||||||
return popen_obj
|
if 'cwd' in kwargs:
|
||||||
|
cmd_kwargs['cwd'] = kwargs['cwd']
|
||||||
|
|
||||||
|
return subprocess.Popen(**cmd_kwargs)
|
||||||
|
|
||||||
def print_error(*args, **kwargs):
|
def print_error(*args, **kwargs):
|
||||||
"""Prints message to screen in RED."""
|
"""Prints message to screen in RED."""
|
||||||
|
|
@ -454,7 +462,7 @@ def print_log(message='', end='\n', timestamp=True):
|
||||||
line = line,
|
line = line,
|
||||||
end = end))
|
end = end))
|
||||||
|
|
||||||
def run_program(cmd, args=[], check=True, pipe=True, shell=False):
|
def run_program(cmd, args=[], check=True, pipe=True, shell=False, **kwargs):
|
||||||
"""Run program and return a subprocess.CompletedProcess object."""
|
"""Run program and return a subprocess.CompletedProcess object."""
|
||||||
if args:
|
if args:
|
||||||
# Deprecated so let's raise an exception to find & fix all occurances
|
# Deprecated so let's raise an exception to find & fix all occurances
|
||||||
|
|
@ -464,13 +472,18 @@ def run_program(cmd, args=[], check=True, pipe=True, shell=False):
|
||||||
if shell:
|
if shell:
|
||||||
cmd = ' '.join(cmd)
|
cmd = ' '.join(cmd)
|
||||||
|
|
||||||
if pipe:
|
cmd_kwargs = {'args': cmd, 'check': check, 'shell': shell}
|
||||||
process_return = subprocess.run(cmd, check=check, shell=shell,
|
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
else:
|
|
||||||
process_return = subprocess.run(cmd, check=check, shell=shell)
|
|
||||||
|
|
||||||
return process_return
|
if pipe:
|
||||||
|
cmd_kwargs.update({
|
||||||
|
'stdout': subprocess.PIPE,
|
||||||
|
'stderr': subprocess.PIPE,
|
||||||
|
})
|
||||||
|
|
||||||
|
if 'cwd' in kwargs:
|
||||||
|
cmd_kwargs['cwd'] = kwargs['cwd']
|
||||||
|
|
||||||
|
return subprocess.run(**cmd_kwargs)
|
||||||
|
|
||||||
def set_title(title='~Some Title~'):
|
def set_title(title='~Some Title~'):
|
||||||
"""Set title.
|
"""Set title.
|
||||||
|
|
@ -513,6 +526,12 @@ def stay_awake():
|
||||||
print_error('ERROR: No caffeine available.')
|
print_error('ERROR: No caffeine available.')
|
||||||
print_warning('Please set the power setting to High Performance.')
|
print_warning('Please set the power setting to High Performance.')
|
||||||
|
|
||||||
|
def strip_colors(s):
|
||||||
|
"""Remove all ASCII color escapes from string, returns str."""
|
||||||
|
for c in COLORS.values():
|
||||||
|
s = s.replace(c, '')
|
||||||
|
return s
|
||||||
|
|
||||||
def get_exception(s):
|
def get_exception(s):
|
||||||
"""Get exception by name, returns Exception object."""
|
"""Get exception by name, returns Exception object."""
|
||||||
try:
|
try:
|
||||||
|
|
@ -636,8 +655,9 @@ def wait_for_process(name, poll_rate=3):
|
||||||
sleep(1)
|
sleep(1)
|
||||||
|
|
||||||
# global_vars functions
|
# global_vars functions
|
||||||
def init_global_vars():
|
def init_global_vars(silent=False):
|
||||||
"""Sets global variables based on system info."""
|
"""Sets global variables based on system info."""
|
||||||
|
if not silent:
|
||||||
print_info('Initializing')
|
print_info('Initializing')
|
||||||
if psutil.WINDOWS:
|
if psutil.WINDOWS:
|
||||||
os.system('title Wizard Kit')
|
os.system('title Wizard Kit')
|
||||||
|
|
@ -656,6 +676,10 @@ def init_global_vars():
|
||||||
['Clearing collisions...', clean_env_vars],
|
['Clearing collisions...', clean_env_vars],
|
||||||
]
|
]
|
||||||
try:
|
try:
|
||||||
|
if silent:
|
||||||
|
for f in init_functions:
|
||||||
|
f[1]()
|
||||||
|
else:
|
||||||
for f in init_functions:
|
for f in init_functions:
|
||||||
try_and_print(
|
try_and_print(
|
||||||
message=f[0], function=f[1],
|
message=f[0], function=f[1],
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,11 @@ import signal
|
||||||
import stat
|
import stat
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from collections import OrderedDict
|
||||||
from functions.common import *
|
from functions.common import *
|
||||||
from functions.data import *
|
from functions.data import *
|
||||||
|
from functions.hw_diags import *
|
||||||
|
from functions.tmux import *
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
# STATIC VARIABLES
|
# STATIC VARIABLES
|
||||||
|
|
@ -30,6 +33,11 @@ DDRESCUE_SETTINGS = {
|
||||||
}
|
}
|
||||||
RECOMMENDED_FSTYPES = ['ext3', 'ext4', 'xfs']
|
RECOMMENDED_FSTYPES = ['ext3', 'ext4', 'xfs']
|
||||||
SIDE_PANE_WIDTH = 21
|
SIDE_PANE_WIDTH = 21
|
||||||
|
TMUX_LAYOUT = OrderedDict({
|
||||||
|
'Source': {'y': 2, 'Check': True},
|
||||||
|
'Started': {'x': SIDE_PANE_WIDTH, 'Check': True},
|
||||||
|
'Progress': {'x': SIDE_PANE_WIDTH, 'Check': True},
|
||||||
|
})
|
||||||
USAGE = """ {script_name} clone [source [destination]]
|
USAGE = """ {script_name} clone [source [destination]]
|
||||||
{script_name} image [source [destination]]
|
{script_name} image [source [destination]]
|
||||||
(e.g. {script_name} clone /dev/sda /dev/sdb)
|
(e.g. {script_name} clone /dev/sda /dev/sdb)
|
||||||
|
|
@ -276,6 +284,7 @@ class RecoveryState():
|
||||||
self.current_pass_str = '0: Initializing'
|
self.current_pass_str = '0: Initializing'
|
||||||
self.settings = DDRESCUE_SETTINGS.copy()
|
self.settings = DDRESCUE_SETTINGS.copy()
|
||||||
self.finished = False
|
self.finished = False
|
||||||
|
self.panes = {}
|
||||||
self.progress_out = '{}/progress.out'.format(global_vars['LogDir'])
|
self.progress_out = '{}/progress.out'.format(global_vars['LogDir'])
|
||||||
self.rescued = 0
|
self.rescued = 0
|
||||||
self.resumed = False
|
self.resumed = False
|
||||||
|
|
@ -283,6 +292,7 @@ class RecoveryState():
|
||||||
self.total_size = 0
|
self.total_size = 0
|
||||||
if mode not in ('clone', 'image'):
|
if mode not in ('clone', 'image'):
|
||||||
raise GenericError('Unsupported mode')
|
raise GenericError('Unsupported mode')
|
||||||
|
self.get_smart_source()
|
||||||
|
|
||||||
def add_block_pair(self, source, dest):
|
def add_block_pair(self, source, dest):
|
||||||
"""Run safety checks and append new BlockPair to internal list."""
|
"""Run safety checks and append new BlockPair to internal list."""
|
||||||
|
|
@ -341,6 +351,14 @@ class RecoveryState():
|
||||||
min_percent = min(min_percent, bp.rescued_percent)
|
min_percent = min(min_percent, bp.rescued_percent)
|
||||||
return min_percent
|
return min_percent
|
||||||
|
|
||||||
|
def get_smart_source(self):
|
||||||
|
"""Get source for SMART dispay."""
|
||||||
|
disk_path = self.source.path
|
||||||
|
if self.source.parent:
|
||||||
|
disk_path = self.source.parent
|
||||||
|
|
||||||
|
self.smart_source = DiskObj(disk_path)
|
||||||
|
|
||||||
def retry_all_passes(self):
|
def retry_all_passes(self):
|
||||||
"""Mark all passes as pending for all block-pairs."""
|
"""Mark all passes as pending for all block-pairs."""
|
||||||
self.finished = False
|
self.finished = False
|
||||||
|
|
@ -351,7 +369,34 @@ class RecoveryState():
|
||||||
self.set_pass_num()
|
self.set_pass_num()
|
||||||
|
|
||||||
def self_checks(self):
|
def self_checks(self):
|
||||||
"""Run self-checks for each BlockPair and update state values."""
|
"""Run self-checks and update state values."""
|
||||||
|
cmd = ['findmnt', '--json', '--target', os.getcwd()]
|
||||||
|
map_allowed_fstypes = RECOMMENDED_FSTYPES.copy()
|
||||||
|
map_allowed_fstypes.extend(['cifs', 'ext2', 'vfat'])
|
||||||
|
map_allowed_fstypes.sort()
|
||||||
|
json_data = {}
|
||||||
|
|
||||||
|
# Avoid saving map to non-persistent filesystem
|
||||||
|
try:
|
||||||
|
result = run_program(cmd)
|
||||||
|
json_data = json.loads(result.stdout.decode())
|
||||||
|
except Exception:
|
||||||
|
print_error('ERROR: Failed to verify map path')
|
||||||
|
raise GenericAbort()
|
||||||
|
fstype = json_data.get(
|
||||||
|
'filesystems', [{}])[0].get(
|
||||||
|
'fstype', 'unknown')
|
||||||
|
if fstype not in map_allowed_fstypes:
|
||||||
|
print_error(
|
||||||
|
"Map isn't being saved to a recommended filesystem ({})".format(
|
||||||
|
fstype.upper()))
|
||||||
|
print_info('Recommended types are: {}'.format(
|
||||||
|
' / '.join(map_allowed_fstypes).upper()))
|
||||||
|
print_standard(' ')
|
||||||
|
if not ask('Proceed anyways? (Strongly discouraged)'):
|
||||||
|
raise GenericAbort()
|
||||||
|
|
||||||
|
# Run BlockPair self checks and get total size
|
||||||
self.total_size = 0
|
self.total_size = 0
|
||||||
for bp in self.block_pairs:
|
for bp in self.block_pairs:
|
||||||
bp.self_check()
|
bp.self_check()
|
||||||
|
|
@ -398,46 +443,22 @@ class RecoveryState():
|
||||||
# Functions
|
# Functions
|
||||||
def build_outer_panes(state):
|
def build_outer_panes(state):
|
||||||
"""Build top and side panes."""
|
"""Build top and side panes."""
|
||||||
clear_screen()
|
state.panes['Source'] = tmux_split_window(
|
||||||
result = run_program(['tput', 'cols'])
|
behind=True, vertical=True, lines=2,
|
||||||
width = int(
|
text='{BLUE}Source{CLEAR}'.format(**COLORS))
|
||||||
(int(result.stdout.decode().strip()) - SIDE_PANE_WIDTH) / 2) - 2
|
state.panes['Started'] = tmux_split_window(
|
||||||
|
lines=SIDE_PANE_WIDTH, target_pane=state.panes['Source'],
|
||||||
# Top panes
|
text='{BLUE}Started{CLEAR}\n{s}'.format(
|
||||||
source_str = state.source.name
|
s=time.strftime("%Y-%m-%d %H:%M %Z"),
|
||||||
if len(source_str) > width:
|
|
||||||
source_str = '{}...'.format(source_str[:width-3])
|
|
||||||
dest_str = state.dest.name
|
|
||||||
if len(dest_str) > width:
|
|
||||||
if state.mode == 'clone':
|
|
||||||
dest_str = '{}...'.format(dest_str[:width-3])
|
|
||||||
else:
|
|
||||||
dest_str = '...{}'.format(dest_str[-width+3:])
|
|
||||||
source_pane = tmux_splitw(
|
|
||||||
'-bdvl', '2',
|
|
||||||
'-PF', '#D',
|
|
||||||
'echo-and-hold "{BLUE}Source{CLEAR}\n{text}"'.format(
|
|
||||||
text=source_str,
|
|
||||||
**COLORS))
|
|
||||||
tmux_splitw(
|
|
||||||
'-t', source_pane,
|
|
||||||
'-dhl', '{}'.format(SIDE_PANE_WIDTH),
|
|
||||||
'echo-and-hold "{BLUE}Started{CLEAR}\n{text}"'.format(
|
|
||||||
text=time.strftime("%Y-%m-%d %H:%M %Z"),
|
|
||||||
**COLORS))
|
|
||||||
tmux_splitw(
|
|
||||||
'-t', source_pane,
|
|
||||||
'-dhp', '50',
|
|
||||||
'echo-and-hold "{BLUE}Destination{CLEAR}\n{text}"'.format(
|
|
||||||
text=dest_str,
|
|
||||||
**COLORS))
|
**COLORS))
|
||||||
|
state.panes['Destination'] = tmux_split_window(
|
||||||
|
percent=50, target_pane=state.panes['Source'],
|
||||||
|
text='{BLUE}Destination{CLEAR}'.format(**COLORS))
|
||||||
|
|
||||||
# Side pane
|
# Side pane
|
||||||
update_sidepane(state)
|
update_sidepane(state)
|
||||||
tmux_splitw(
|
state.panes['Progress'] = tmux_split_window(
|
||||||
'-dhl', str(SIDE_PANE_WIDTH),
|
lines=SIDE_PANE_WIDTH, watch=state.progress_out)
|
||||||
'watch', '--color', '--no-title', '--interval', '1',
|
|
||||||
'cat', state.progress_out)
|
|
||||||
|
|
||||||
|
|
||||||
def create_path_obj(path):
|
def create_path_obj(path):
|
||||||
|
|
@ -464,6 +485,94 @@ def double_confirm_clone():
|
||||||
return ask('Asking again to confirm, is this correct?')
|
return ask('Asking again to confirm, is this correct?')
|
||||||
|
|
||||||
|
|
||||||
|
def fix_tmux_panes(state, forced=False):
|
||||||
|
"""Fix pane sizes if the winodw has been resized."""
|
||||||
|
needs_fixed = False
|
||||||
|
|
||||||
|
# Check layout
|
||||||
|
for k, v in TMUX_LAYOUT.items():
|
||||||
|
if not v.get('Check'):
|
||||||
|
# Not concerned with the size of this pane
|
||||||
|
continue
|
||||||
|
# Get target
|
||||||
|
target = None
|
||||||
|
if k != 'Current':
|
||||||
|
if k not in state.panes:
|
||||||
|
# Skip missing panes
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
target = state.panes[k]
|
||||||
|
|
||||||
|
# Check pane size
|
||||||
|
x, y = tmux_get_pane_size(pane_id=target)
|
||||||
|
if v.get('x', False) and v['x'] != x:
|
||||||
|
needs_fixed = True
|
||||||
|
if v.get('y', False) and v['y'] != y:
|
||||||
|
needs_fixed = True
|
||||||
|
|
||||||
|
# Bail?
|
||||||
|
if not needs_fixed and not forced:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Remove Destination pane (temporarily)
|
||||||
|
tmux_kill_pane(state.panes['Destination'])
|
||||||
|
|
||||||
|
# Update layout
|
||||||
|
for k, v in TMUX_LAYOUT.items():
|
||||||
|
# Get target
|
||||||
|
target = None
|
||||||
|
if k != 'Current':
|
||||||
|
if k not in state.panes:
|
||||||
|
# Skip missing panes
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
target = state.panes[k]
|
||||||
|
|
||||||
|
# Resize pane
|
||||||
|
tmux_resize_pane(pane_id=target, **v)
|
||||||
|
|
||||||
|
# Calc Source/Destination pane sizes
|
||||||
|
width, height = tmux_get_pane_size()
|
||||||
|
width = int(width / 2) - 1
|
||||||
|
|
||||||
|
# Update Source string
|
||||||
|
source_str = state.source.name
|
||||||
|
if len(source_str) > width:
|
||||||
|
source_str = '{}...'.format(source_str[:width-3])
|
||||||
|
|
||||||
|
# Update Destination string
|
||||||
|
dest_str = state.dest.name
|
||||||
|
if len(dest_str) > width:
|
||||||
|
if state.mode == 'clone':
|
||||||
|
dest_str = '{}...'.format(dest_str[:width-3])
|
||||||
|
else:
|
||||||
|
dest_str = '...{}'.format(dest_str[-width+3:])
|
||||||
|
|
||||||
|
# Rebuild Source/Destination panes
|
||||||
|
tmux_update_pane(
|
||||||
|
pane_id=state.panes['Source'],
|
||||||
|
text='{BLUE}Source{CLEAR}\n{s}'.format(
|
||||||
|
s=source_str, **COLORS))
|
||||||
|
state.panes['Destination'] = tmux_split_window(
|
||||||
|
percent=50, target_pane=state.panes['Source'],
|
||||||
|
text='{BLUE}Destination{CLEAR}\n{s}'.format(
|
||||||
|
s=dest_str, **COLORS))
|
||||||
|
|
||||||
|
if 'SMART' in state.panes:
|
||||||
|
# Calc SMART/ddrescue/Journal panes sizes
|
||||||
|
ratio = [12, 22, 4]
|
||||||
|
width, height = tmux_get_pane_size(pane_id=state.panes['Progress'])
|
||||||
|
height -= 2
|
||||||
|
total = sum(ratio)
|
||||||
|
p_ratio = [int((x/total) * height) for x in ratio]
|
||||||
|
p_ratio[1] = height - p_ratio[0] - p_ratio[2]
|
||||||
|
|
||||||
|
# Resize SMART/Journal panes
|
||||||
|
tmux_resize_pane(state.panes['SMART'], y=ratio[0])
|
||||||
|
tmux_resize_pane(y=ratio[1])
|
||||||
|
tmux_resize_pane(state.panes['Journal'], y=ratio[2])
|
||||||
|
|
||||||
|
|
||||||
def get_device_details(dev_path):
|
def get_device_details(dev_path):
|
||||||
"""Get device details via lsblk, returns JSON dict."""
|
"""Get device details via lsblk, returns JSON dict."""
|
||||||
try:
|
try:
|
||||||
|
|
@ -660,7 +769,9 @@ def menu_ddrescue(source_path, dest_path, run_mode):
|
||||||
raise GenericAbort()
|
raise GenericAbort()
|
||||||
|
|
||||||
# Main menu
|
# Main menu
|
||||||
|
clear_screen()
|
||||||
build_outer_panes(state)
|
build_outer_panes(state)
|
||||||
|
fix_tmux_panes(state, forced=True)
|
||||||
menu_main(state)
|
menu_main(state)
|
||||||
|
|
||||||
# Done
|
# Done
|
||||||
|
|
@ -842,7 +953,8 @@ def read_map_file(map_path):
|
||||||
|
|
||||||
def run_ddrescue(state, pass_settings):
|
def run_ddrescue(state, pass_settings):
|
||||||
"""Run ddrescue pass."""
|
"""Run ddrescue pass."""
|
||||||
return_code = None
|
return_code = -1
|
||||||
|
aborted = False
|
||||||
|
|
||||||
if state.finished:
|
if state.finished:
|
||||||
clear_screen()
|
clear_screen()
|
||||||
|
|
@ -850,29 +962,21 @@ def run_ddrescue(state, pass_settings):
|
||||||
pause('Press Enter to return to main menu...')
|
pause('Press Enter to return to main menu...')
|
||||||
return
|
return
|
||||||
|
|
||||||
# Set heights
|
# Create SMART monitor pane
|
||||||
# NOTE: 12/33 is based on min heights for SMART/ddrescue panes (12+22+1sep)
|
state.smart_out = '{}/smart_{}.out'.format(
|
||||||
result = run_program(['tput', 'lines'])
|
global_vars['TmpDir'], state.smart_source.name)
|
||||||
height = int(result.stdout.decode().strip())
|
with open(state.smart_out, 'w') as f:
|
||||||
height_smart = int(height * (8 / 33))
|
f.write('Initializing...')
|
||||||
height_journal = int(height * (4 / 33))
|
state.panes['SMART'] = tmux_split_window(
|
||||||
height_ddrescue = height - height_smart - height_journal
|
behind=True, lines=12, vertical=True, watch=state.smart_out)
|
||||||
|
|
||||||
# Show SMART status
|
|
||||||
smart_dev = state.source_path
|
|
||||||
if state.source.parent:
|
|
||||||
smart_dev = state.source.parent
|
|
||||||
smart_pane = tmux_splitw(
|
|
||||||
'-bdvl', str(height_smart),
|
|
||||||
'-PF', '#D',
|
|
||||||
'watch', '--color', '--no-title', '--interval', '300',
|
|
||||||
'ddrescue-tui-smart-display', smart_dev)
|
|
||||||
|
|
||||||
# Show systemd journal output
|
# Show systemd journal output
|
||||||
journal_pane = tmux_splitw(
|
state.panes['Journal'] = tmux_split_window(
|
||||||
'-dvl', str(height_journal),
|
lines=4, vertical=True,
|
||||||
'-PF', '#D',
|
command=['sudo', 'journalctl', '-f'])
|
||||||
'journalctl', '-f')
|
|
||||||
|
# Fix layout
|
||||||
|
fix_tmux_panes(state, forced=True)
|
||||||
|
|
||||||
# Run pass for each block-pair
|
# Run pass for each block-pair
|
||||||
for bp in state.block_pairs:
|
for bp in state.block_pairs:
|
||||||
|
|
@ -901,21 +1005,40 @@ def run_ddrescue(state, pass_settings):
|
||||||
clear_screen()
|
clear_screen()
|
||||||
print_info('Current dev: {}'.format(bp.source_path))
|
print_info('Current dev: {}'.format(bp.source_path))
|
||||||
ddrescue_proc = popen_program(cmd)
|
ddrescue_proc = popen_program(cmd)
|
||||||
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
|
# Update SMART display (every 30 seconds)
|
||||||
|
if i % 30 == 0:
|
||||||
|
state.smart_source.get_smart_details()
|
||||||
|
with open(state.smart_out, 'w') as f:
|
||||||
|
report = state.smart_source.generate_attribute_report(
|
||||||
|
timestamp=True)
|
||||||
|
for line in report:
|
||||||
|
f.write('{}\n'.format(line))
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
# Update progress
|
||||||
bp.update_progress(state.current_pass)
|
bp.update_progress(state.current_pass)
|
||||||
update_sidepane(state)
|
update_sidepane(state)
|
||||||
|
|
||||||
|
# Fix panes
|
||||||
|
fix_tmux_panes(state)
|
||||||
|
|
||||||
|
# Check if ddrescue has finished
|
||||||
try:
|
try:
|
||||||
ddrescue_proc.wait(timeout=10)
|
ddrescue_proc.wait(timeout=1)
|
||||||
sleep(2)
|
sleep(2)
|
||||||
bp.update_progress(state.current_pass)
|
bp.update_progress(state.current_pass)
|
||||||
update_sidepane(state)
|
update_sidepane(state)
|
||||||
break
|
break
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
# Catch to update bp/sidepane
|
# Catch to update smart/bp/sidepane
|
||||||
pass
|
pass
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
# Catch user abort
|
# Catch user abort
|
||||||
pass
|
aborted = True
|
||||||
|
ddrescue_proc.wait(timeout=10)
|
||||||
|
|
||||||
# Update progress/sidepane again
|
# Update progress/sidepane again
|
||||||
bp.update_progress(state.current_pass)
|
bp.update_progress(state.current_pass)
|
||||||
|
|
@ -923,12 +1046,19 @@ def run_ddrescue(state, pass_settings):
|
||||||
|
|
||||||
# Was ddrescue aborted?
|
# Was ddrescue aborted?
|
||||||
return_code = ddrescue_proc.poll()
|
return_code = ddrescue_proc.poll()
|
||||||
if return_code is None or return_code is 130:
|
if aborted:
|
||||||
clear_screen()
|
print_standard(' ')
|
||||||
|
print_standard(' ')
|
||||||
|
print_error('DDRESCUE PROCESS HALTED')
|
||||||
|
print_standard(' ')
|
||||||
print_warning('Aborted')
|
print_warning('Aborted')
|
||||||
break
|
break
|
||||||
elif return_code:
|
elif return_code:
|
||||||
# i.e. not None and not 0
|
# i.e. True when non-zero
|
||||||
|
print_standard(' ')
|
||||||
|
print_standard(' ')
|
||||||
|
print_error('DDRESCUE PROCESS HALTED')
|
||||||
|
print_standard(' ')
|
||||||
print_error('Error(s) encountered, see message above.')
|
print_error('Error(s) encountered, see message above.')
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
|
@ -940,8 +1070,9 @@ def run_ddrescue(state, pass_settings):
|
||||||
if str(return_code) != '0':
|
if str(return_code) != '0':
|
||||||
# Pause on errors
|
# Pause on errors
|
||||||
pause('Press Enter to return to main menu... ')
|
pause('Press Enter to return to main menu... ')
|
||||||
run_program(['tmux', 'kill-pane', '-t', smart_pane])
|
|
||||||
run_program(['tmux', 'kill-pane', '-t', journal_pane])
|
# Cleanup
|
||||||
|
tmux_kill_pane(state.panes['SMART'], state.panes['Journal'])
|
||||||
|
|
||||||
|
|
||||||
def select_parts(source_device):
|
def select_parts(source_device):
|
||||||
|
|
@ -1192,13 +1323,6 @@ def show_usage(script_name):
|
||||||
pause()
|
pause()
|
||||||
|
|
||||||
|
|
||||||
def tmux_splitw(*args):
|
|
||||||
"""Run tmux split-window command and return output as str."""
|
|
||||||
cmd = ['tmux', 'split-window', *args]
|
|
||||||
result = run_program(cmd)
|
|
||||||
return result.stdout.decode().strip()
|
|
||||||
|
|
||||||
|
|
||||||
def update_sidepane(state):
|
def update_sidepane(state):
|
||||||
"""Update progress file for side pane."""
|
"""Update progress file for side pane."""
|
||||||
output = []
|
output = []
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
198
.bin/Scripts/functions/sensors.py
Normal file
198
.bin/Scripts/functions/sensors.py
Normal file
|
|
@ -0,0 +1,198 @@
|
||||||
|
# Wizard Kit: Functions - Sensors
|
||||||
|
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
|
||||||
|
from functions.tmux import *
|
||||||
|
|
||||||
|
# STATIC VARIABLES
|
||||||
|
TEMP_LIMITS = {
|
||||||
|
'GREEN': 60,
|
||||||
|
'YELLOW': 70,
|
||||||
|
'ORANGE': 80,
|
||||||
|
'RED': 90,
|
||||||
|
}
|
||||||
|
|
||||||
|
# REGEX
|
||||||
|
REGEX_COLORS = re.compile(r'\033\[\d+;?1?m')
|
||||||
|
|
||||||
|
def clear_temps(sensor_data):
|
||||||
|
"""Clear saved temps but keep structure, returns dict."""
|
||||||
|
for _section, _adapters in sensor_data.items():
|
||||||
|
for _adapter, _sources in _adapters.items():
|
||||||
|
for _source, _data in _sources.items():
|
||||||
|
_data['Temps'] = []
|
||||||
|
|
||||||
|
def fix_sensor_str(s):
|
||||||
|
"""Cleanup string and return str."""
|
||||||
|
s = re.sub(r'^(\w+)-(\w+)-(\w+)', r'\1 (\2 \3)', s, re.IGNORECASE)
|
||||||
|
s = s.title()
|
||||||
|
s = s.replace('Coretemp', 'CoreTemp')
|
||||||
|
s = s.replace('Acpi', 'ACPI')
|
||||||
|
s = s.replace('ACPItz', 'ACPI TZ')
|
||||||
|
s = s.replace('Isa ', 'ISA ')
|
||||||
|
s = s.replace('Id ', 'ID ')
|
||||||
|
s = re.sub(r'(\D+)(\d+)', r'\1 \2', s, re.IGNORECASE)
|
||||||
|
s = s.replace(' ', ' ')
|
||||||
|
return s
|
||||||
|
|
||||||
|
def generate_sensor_report(
|
||||||
|
sensor_data, *temp_labels,
|
||||||
|
colors=True, core_only=False):
|
||||||
|
"""Generate report based on temp_labels, returns list if str."""
|
||||||
|
report = []
|
||||||
|
for _section, _adapters in sorted(sensor_data.items()):
|
||||||
|
# CoreTemps then Other temps
|
||||||
|
if core_only and 'Core' not in _section:
|
||||||
|
continue
|
||||||
|
for _adapter, _sources in sorted(_adapters.items()):
|
||||||
|
# Adapter
|
||||||
|
report.append(fix_sensor_str(_adapter))
|
||||||
|
for _source, _data in sorted(_sources.items()):
|
||||||
|
# Source
|
||||||
|
_line = '{:18} '.format(fix_sensor_str(_source))
|
||||||
|
# Temps (skip label for Current)
|
||||||
|
for _label in temp_labels:
|
||||||
|
_line += '{}{}{} '.format(
|
||||||
|
_label.lower() if _label != 'Current' else '',
|
||||||
|
': ' if _label != 'Current' else '',
|
||||||
|
get_temp_str(_data.get(_label, '???'), colors=colors))
|
||||||
|
report.append(_line)
|
||||||
|
if not core_only:
|
||||||
|
report.append(' ')
|
||||||
|
|
||||||
|
# Handle empty reports (i.e. no sensors detected)
|
||||||
|
if not report:
|
||||||
|
report = [
|
||||||
|
'{}WARNING: No sensors found{}'.format(
|
||||||
|
COLORS['YELLOW'] if colors else '',
|
||||||
|
COLORS['CLEAR'] if colors else ''),
|
||||||
|
' ',
|
||||||
|
'Please monitor temps manually']
|
||||||
|
|
||||||
|
# Done
|
||||||
|
return report
|
||||||
|
|
||||||
|
def get_colored_temp_str(temp):
|
||||||
|
"""Get colored string based on temp, returns str."""
|
||||||
|
try:
|
||||||
|
temp = float(temp)
|
||||||
|
except ValueError:
|
||||||
|
return '{YELLOW}{temp}{CLEAR}'.format(temp=temp, **COLORS)
|
||||||
|
if temp > TEMP_LIMITS['RED']:
|
||||||
|
color = COLORS['RED']
|
||||||
|
elif temp > TEMP_LIMITS['ORANGE']:
|
||||||
|
color = COLORS['ORANGE']
|
||||||
|
elif temp > TEMP_LIMITS['YELLOW']:
|
||||||
|
color = COLORS['YELLOW']
|
||||||
|
elif temp > TEMP_LIMITS['GREEN']:
|
||||||
|
color = COLORS['GREEN']
|
||||||
|
elif temp > 0:
|
||||||
|
color = COLORS['BLUE']
|
||||||
|
else:
|
||||||
|
color = COLORS['CLEAR']
|
||||||
|
return '{color}{prefix}{temp:2.0f}°C{CLEAR}'.format(
|
||||||
|
color = color,
|
||||||
|
prefix = '-' if temp < 0 else '',
|
||||||
|
temp = temp,
|
||||||
|
**COLORS)
|
||||||
|
|
||||||
|
def get_raw_sensor_data():
|
||||||
|
"""Read sensor data and return dict."""
|
||||||
|
cmd = ['sensors', '-j']
|
||||||
|
result = run_program(cmd)
|
||||||
|
return json.loads(result.stdout.decode())
|
||||||
|
|
||||||
|
def get_sensor_data():
|
||||||
|
"""Parse raw sensor data and return new dict."""
|
||||||
|
json_data = get_raw_sensor_data()
|
||||||
|
sensor_data = {'CoreTemps': {}, 'Other': {}}
|
||||||
|
for _adapter, _sources in json_data.items():
|
||||||
|
if 'coretemp' in _adapter:
|
||||||
|
_section = 'CoreTemps'
|
||||||
|
else:
|
||||||
|
_section = 'Other'
|
||||||
|
sensor_data[_section][_adapter] = {}
|
||||||
|
_sources.pop('Adapter', None)
|
||||||
|
|
||||||
|
# Find current temp and add to dict
|
||||||
|
## current temp is labeled xxxx_input
|
||||||
|
for _source, _labels in _sources.items():
|
||||||
|
for _label, _temp in _labels.items():
|
||||||
|
if 'input' in _label:
|
||||||
|
sensor_data[_section][_adapter][_source] = {
|
||||||
|
'Current': _temp,
|
||||||
|
'Label': _label,
|
||||||
|
'Max': _temp,
|
||||||
|
'Temps': [_temp],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove empty sections
|
||||||
|
for k, v in sensor_data.items():
|
||||||
|
v = {k2: v2 for k2, v2 in v.items() if v2}
|
||||||
|
|
||||||
|
# Done
|
||||||
|
return sensor_data
|
||||||
|
|
||||||
|
def get_temp_str(temp, colors=True):
|
||||||
|
"""Get temp string, returns str."""
|
||||||
|
if colors:
|
||||||
|
return get_colored_temp_str(temp)
|
||||||
|
try:
|
||||||
|
temp = float(temp)
|
||||||
|
except ValueError:
|
||||||
|
return '{}'.format(temp)
|
||||||
|
else:
|
||||||
|
return '{}{:2.0f}°C'.format(
|
||||||
|
'-' if temp < 0 else '',
|
||||||
|
temp)
|
||||||
|
|
||||||
|
def monitor_sensors(monitor_pane, monitor_file):
|
||||||
|
"""Continually update sensor data and report to screen."""
|
||||||
|
sensor_data = get_sensor_data()
|
||||||
|
while True:
|
||||||
|
update_sensor_data(sensor_data)
|
||||||
|
with open(monitor_file, 'w') as f:
|
||||||
|
report = generate_sensor_report(sensor_data, 'Current', 'Max')
|
||||||
|
f.write('\n'.join(report))
|
||||||
|
sleep(1)
|
||||||
|
if monitor_pane and not tmux_poll_pane(monitor_pane):
|
||||||
|
break
|
||||||
|
|
||||||
|
def save_average_temp(sensor_data, temp_label, seconds=10):
|
||||||
|
"""Calculate average temps and record under temp_label, returns dict."""
|
||||||
|
clear_temps(sensor_data)
|
||||||
|
|
||||||
|
# Get temps
|
||||||
|
for i in range(seconds):
|
||||||
|
update_sensor_data(sensor_data)
|
||||||
|
sleep(1)
|
||||||
|
|
||||||
|
# Calculate averages
|
||||||
|
for _section, _adapters in sensor_data.items():
|
||||||
|
for _adapter, _sources in _adapters.items():
|
||||||
|
for _source, _data in _sources.items():
|
||||||
|
_data[temp_label] = sum(_data['Temps']) / len(_data['Temps'])
|
||||||
|
|
||||||
|
def update_sensor_data(sensor_data):
|
||||||
|
"""Read sensors and update existing sensor_data, returns dict."""
|
||||||
|
json_data = get_raw_sensor_data()
|
||||||
|
for _section, _adapters in sensor_data.items():
|
||||||
|
for _adapter, _sources in _adapters.items():
|
||||||
|
for _source, _data in _sources.items():
|
||||||
|
_label = _data['Label']
|
||||||
|
_temp = json_data[_adapter][_source][_label]
|
||||||
|
_data['Current'] = _temp
|
||||||
|
_data['Max'] = max(_temp, _data['Max'])
|
||||||
|
_data['Temps'].append(_temp)
|
||||||
|
|
||||||
|
def join_columns(column1, column2, width=55):
|
||||||
|
return '{:<{}}{}'.format(
|
||||||
|
column1,
|
||||||
|
55+len(column1)-len(REGEX_COLORS.sub('', column1)),
|
||||||
|
column2)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print("This file is not meant to be called directly.")
|
||||||
|
|
||||||
|
# vim: sts=2 sw=2 ts=2
|
||||||
148
.bin/Scripts/functions/tmux.py
Normal file
148
.bin/Scripts/functions/tmux.py
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
# Wizard Kit: Functions - tmux
|
||||||
|
|
||||||
|
from functions.common import *
|
||||||
|
|
||||||
|
def create_file(filepath):
|
||||||
|
"""Create file if it doesn't exist."""
|
||||||
|
if not os.path.exists(filepath):
|
||||||
|
with open(filepath, 'w') as f:
|
||||||
|
f.write('')
|
||||||
|
|
||||||
|
def tmux_get_pane_size(pane_id=None):
|
||||||
|
"""Get target, or current, pane size, returns tuple."""
|
||||||
|
x = -1
|
||||||
|
y = -1
|
||||||
|
cmd = ['tmux', 'display', '-p']
|
||||||
|
if pane_id:
|
||||||
|
cmd.extend(['-t', pane_id])
|
||||||
|
cmd.append('#{pane_width} #{pane_height}')
|
||||||
|
|
||||||
|
# Run cmd and set x & y
|
||||||
|
result = run_program(cmd, check=False)
|
||||||
|
try:
|
||||||
|
x, y = result.stdout.decode().strip().split()
|
||||||
|
x = int(x)
|
||||||
|
y = int(y)
|
||||||
|
except Exception:
|
||||||
|
# Ignore and return unrealistic values
|
||||||
|
pass
|
||||||
|
|
||||||
|
return (x, y)
|
||||||
|
|
||||||
|
def tmux_kill_all_panes(pane_id=None):
|
||||||
|
"""Kill all tmux panes except the active pane or pane_id if specified."""
|
||||||
|
cmd = ['tmux', 'kill-pane', '-a']
|
||||||
|
if pane_id:
|
||||||
|
cmd.extend(['-t', pane_id])
|
||||||
|
run_program(cmd, check=False)
|
||||||
|
|
||||||
|
def tmux_kill_pane(*panes):
|
||||||
|
"""Kill tmux pane by id."""
|
||||||
|
cmd = ['tmux', 'kill-pane', '-t']
|
||||||
|
for pane_id in panes:
|
||||||
|
run_program(cmd+[pane_id], check=False)
|
||||||
|
|
||||||
|
def tmux_poll_pane(pane_id):
|
||||||
|
"""Check if pane exists, returns bool."""
|
||||||
|
cmd = ['tmux', 'list-panes', '-F', '#D']
|
||||||
|
result = run_program(cmd, check=False)
|
||||||
|
panes = result.stdout.decode().splitlines()
|
||||||
|
return pane_id in panes
|
||||||
|
|
||||||
|
def tmux_resize_pane(pane_id=None, x=None, y=None, **kwargs):
|
||||||
|
"""Resize pane to specific hieght or width."""
|
||||||
|
if not x and not y:
|
||||||
|
raise Exception('Neither height nor width specified.')
|
||||||
|
|
||||||
|
cmd = ['tmux', 'resize-pane']
|
||||||
|
if pane_id:
|
||||||
|
# NOTE: If pane_id not specified then the current pane will be resized
|
||||||
|
cmd.extend(['-t', pane_id])
|
||||||
|
if x:
|
||||||
|
cmd.extend(['-x', str(x)])
|
||||||
|
elif y:
|
||||||
|
cmd.extend(['-y', str(y)])
|
||||||
|
|
||||||
|
run_program(cmd, check=False)
|
||||||
|
|
||||||
|
def tmux_split_window(
|
||||||
|
lines=None, percent=None,
|
||||||
|
behind=False, vertical=False,
|
||||||
|
follow=False, target_pane=None,
|
||||||
|
command=None, working_dir=None,
|
||||||
|
text=None, watch=None, watch_cmd='cat'):
|
||||||
|
"""Run tmux split-window command and return pane_id as str."""
|
||||||
|
# Bail early
|
||||||
|
if not lines and not percent:
|
||||||
|
raise Exception('Neither lines nor percent specified.')
|
||||||
|
if not command and not text and not watch:
|
||||||
|
raise Exception('No command, text, or watch file specified.')
|
||||||
|
|
||||||
|
# Build cmd
|
||||||
|
cmd = ['tmux', 'split-window', '-PF', '#D']
|
||||||
|
if behind:
|
||||||
|
cmd.append('-b')
|
||||||
|
if vertical:
|
||||||
|
cmd.append('-v')
|
||||||
|
else:
|
||||||
|
cmd.append('-h')
|
||||||
|
if not follow:
|
||||||
|
cmd.append('-d')
|
||||||
|
if lines is not None:
|
||||||
|
cmd.extend(['-l', str(lines)])
|
||||||
|
elif percent is not None:
|
||||||
|
cmd.extend(['-p', str(percent)])
|
||||||
|
if target_pane:
|
||||||
|
cmd.extend(['-t', str(target_pane)])
|
||||||
|
|
||||||
|
if working_dir:
|
||||||
|
cmd.extend(['-c', working_dir])
|
||||||
|
if command:
|
||||||
|
cmd.extend(command)
|
||||||
|
elif text:
|
||||||
|
cmd.extend(['echo-and-hold "{}"'.format(text)])
|
||||||
|
elif watch:
|
||||||
|
create_file(watch)
|
||||||
|
if watch_cmd == 'cat':
|
||||||
|
cmd.extend([
|
||||||
|
'watch', '--color', '--no-title',
|
||||||
|
'--interval', '1',
|
||||||
|
'cat', watch])
|
||||||
|
elif watch_cmd == 'tail':
|
||||||
|
cmd.extend(['tail', '-f', watch])
|
||||||
|
|
||||||
|
# Run and return pane_id
|
||||||
|
result = run_program(cmd)
|
||||||
|
return result.stdout.decode().strip()
|
||||||
|
|
||||||
|
def tmux_update_pane(
|
||||||
|
pane_id, command=None, working_dir=None,
|
||||||
|
text=None, watch=None, watch_cmd='cat'):
|
||||||
|
"""Respawn with either a new command or new text."""
|
||||||
|
# Bail early
|
||||||
|
if not command and not text and not watch:
|
||||||
|
raise Exception('No command, text, or watch file specified.')
|
||||||
|
|
||||||
|
cmd = ['tmux', 'respawn-pane', '-k', '-t', pane_id]
|
||||||
|
if working_dir:
|
||||||
|
cmd.extend(['-c', working_dir])
|
||||||
|
if command:
|
||||||
|
cmd.extend(command)
|
||||||
|
elif text:
|
||||||
|
cmd.extend(['echo-and-hold "{}"'.format(text)])
|
||||||
|
elif watch:
|
||||||
|
create_file(watch)
|
||||||
|
if watch_cmd == 'cat':
|
||||||
|
cmd.extend([
|
||||||
|
'watch', '--color', '--no-title',
|
||||||
|
'--interval', '1',
|
||||||
|
'cat', watch])
|
||||||
|
elif watch_cmd == 'tail':
|
||||||
|
cmd.extend(['tail', '-f', watch])
|
||||||
|
|
||||||
|
run_program(cmd)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print("This file is not meant to be called directly.")
|
||||||
|
|
||||||
|
# vim: sts=2 sw=2 ts=2
|
||||||
|
|
@ -9,22 +9,29 @@ import sys
|
||||||
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
||||||
sys.path.append(os.getcwd())
|
sys.path.append(os.getcwd())
|
||||||
from functions.hw_diags import *
|
from functions.hw_diags import *
|
||||||
|
from functions.tmux import *
|
||||||
init_global_vars()
|
init_global_vars()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
|
||||||
# Prep
|
|
||||||
clear_screen()
|
|
||||||
|
|
||||||
# Show menu
|
# Show menu
|
||||||
menu_diags(*sys.argv)
|
try:
|
||||||
|
state = State()
|
||||||
# Done
|
menu_diags(state, sys.argv)
|
||||||
#print_standard('\nDone.')
|
except KeyboardInterrupt:
|
||||||
#pause("Press Enter to exit...")
|
print_standard(' ')
|
||||||
exit_script()
|
print_warning('Aborted')
|
||||||
|
print_standard(' ')
|
||||||
|
sleep(1)
|
||||||
|
pause('Press Enter to exit...')
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
|
# Normal exit
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
|
tmux_kill_all_panes()
|
||||||
major_exception()
|
major_exception()
|
||||||
|
|
||||||
|
# Done
|
||||||
|
tmux_kill_all_panes()
|
||||||
|
exit_script()
|
||||||
|
|
||||||
|
# vim: sts=2 sw=2 ts=2
|
||||||
|
|
|
||||||
|
|
@ -14,5 +14,6 @@ if [ ! -d "$1" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run Prime95
|
# Run Prime95
|
||||||
mprime -t | grep -iv --line-buffered 'stress.txt' | tee -a "$1/prime.log"
|
cd "$1"
|
||||||
|
mprime -t | grep -iv --line-buffered 'stress.txt' | tee -a "prime.log"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,168 +1,10 @@
|
||||||
#!/bin/python3
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
## Wizard Kit: Sensor monitoring tool
|
## Wizard Kit: Sensor monitoring tool
|
||||||
|
|
||||||
import itertools
|
WINDOW_NAME="Hardware Sensors"
|
||||||
import os
|
MONITOR="hw-sensors-monitor"
|
||||||
import shutil
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# Init
|
# Start session
|
||||||
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
tmux new-session -n "$WINDOW_NAME" "$MONITOR"
|
||||||
sys.path.append(os.getcwd())
|
|
||||||
from functions.common import *
|
|
||||||
from borrowed import sensors
|
|
||||||
|
|
||||||
# STATIC VARIABLES
|
|
||||||
COLORS = {
|
|
||||||
'CLEAR': '\033[0m',
|
|
||||||
'RED': '\033[31m',
|
|
||||||
'GREEN': '\033[32m',
|
|
||||||
'YELLOW': '\033[33m',
|
|
||||||
'ORANGE': '\033[31;1m',
|
|
||||||
'BLUE': '\033[34m'
|
|
||||||
}
|
|
||||||
TEMP_LIMITS = {
|
|
||||||
'GREEN': 60,
|
|
||||||
'YELLOW': 70,
|
|
||||||
'ORANGE': 80,
|
|
||||||
'RED': 90,
|
|
||||||
}
|
|
||||||
|
|
||||||
# REGEX
|
|
||||||
REGEX_COLORS = re.compile(r'\033\[\d+;?1?m')
|
|
||||||
|
|
||||||
def color_temp(temp):
|
|
||||||
try:
|
|
||||||
temp = float(temp)
|
|
||||||
except ValueError:
|
|
||||||
return '{YELLOW}{temp}{CLEAR}'.format(temp=temp, **COLORS)
|
|
||||||
if temp > TEMP_LIMITS['RED']:
|
|
||||||
color = COLORS['RED']
|
|
||||||
elif temp > TEMP_LIMITS['ORANGE']:
|
|
||||||
color = COLORS['ORANGE']
|
|
||||||
elif temp > TEMP_LIMITS['YELLOW']:
|
|
||||||
color = COLORS['YELLOW']
|
|
||||||
elif temp > TEMP_LIMITS['GREEN']:
|
|
||||||
color = COLORS['GREEN']
|
|
||||||
elif temp > 0:
|
|
||||||
color = COLORS['BLUE']
|
|
||||||
else:
|
|
||||||
color = COLORS['CLEAR']
|
|
||||||
return '{color}{prefix}{temp:2.0f}°C{CLEAR}'.format(
|
|
||||||
color = color,
|
|
||||||
prefix = '-' if temp < 0 else '',
|
|
||||||
temp = temp,
|
|
||||||
**COLORS)
|
|
||||||
|
|
||||||
def get_feature_string(chip, feature):
|
|
||||||
sfs = list(sensors.SubFeatureIterator(chip, feature)) # get a list of all subfeatures
|
|
||||||
label = sensors.get_label(chip, feature)
|
|
||||||
skipname = len(feature.name)+1 # skip common prefix
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
if feature.type != sensors.feature.TEMP:
|
|
||||||
# Skip non-temperature sensors
|
|
||||||
return None
|
|
||||||
|
|
||||||
for sf in sfs:
|
|
||||||
name = sf.name[skipname:].decode("utf-8").strip()
|
|
||||||
try:
|
|
||||||
val = sensors.get_value(chip, sf.number)
|
|
||||||
except Exception:
|
|
||||||
# Ignore upstream sensor bugs and lie instead
|
|
||||||
val = -123456789
|
|
||||||
if 'alarm' in name:
|
|
||||||
# Skip
|
|
||||||
continue
|
|
||||||
if '--nocolor' in sys.argv:
|
|
||||||
try:
|
|
||||||
temp = float(val)
|
|
||||||
except ValueError:
|
|
||||||
data[name] = ' {}°C'.format(val)
|
|
||||||
else:
|
|
||||||
data[name] = '{}{:2.0f}°C'.format(
|
|
||||||
'-' if temp < 0 else '',
|
|
||||||
temp)
|
|
||||||
else:
|
|
||||||
data[name] = color_temp(val)
|
|
||||||
|
|
||||||
main_temp = data.pop('input', None)
|
|
||||||
if main_temp:
|
|
||||||
list_data = []
|
|
||||||
for item in ['max', 'crit']:
|
|
||||||
if item in data:
|
|
||||||
list_data.append('{}: {}'.format(item, data.pop(item)))
|
|
||||||
list_data.extend(
|
|
||||||
['{}: {}'.format(k, v) for k, v in sorted(data.items())])
|
|
||||||
data_str = '{:18} {} {}'.format(
|
|
||||||
label, main_temp, ', '.join(list_data))
|
|
||||||
else:
|
|
||||||
list_data.extend(sorted(data.items()))
|
|
||||||
list_data = ['{}: {}'.format(item[0], item[1]) for item in list_data]
|
|
||||||
data_str = '{:18} {}'.format(label, ', '.join(list_data))
|
|
||||||
return data_str
|
|
||||||
|
|
||||||
def join_columns(column1, column2, width=55):
|
|
||||||
return '{:<{}}{}'.format(
|
|
||||||
column1,
|
|
||||||
55+len(column1)-len(REGEX_COLORS.sub('', column1)),
|
|
||||||
column2)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
try:
|
|
||||||
# Prep
|
|
||||||
sensors.init()
|
|
||||||
|
|
||||||
# Get sensor data
|
|
||||||
chip_temps = {}
|
|
||||||
for chip in sensors.ChipIterator():
|
|
||||||
chip_name = '{} ({})'.format(
|
|
||||||
sensors.chip_snprintf_name(chip),
|
|
||||||
sensors.get_adapter_name(chip.bus))
|
|
||||||
chip_feats = [get_feature_string(chip, feature)
|
|
||||||
for feature in sensors.FeatureIterator(chip)]
|
|
||||||
# Strip empty/None items
|
|
||||||
chip_feats = [f for f in chip_feats if f]
|
|
||||||
|
|
||||||
if chip_feats:
|
|
||||||
chip_temps[chip_name] = [chip_name, *chip_feats, '']
|
|
||||||
|
|
||||||
# Sort chips
|
|
||||||
sensor_temps = []
|
|
||||||
for chip in [k for k in sorted(chip_temps.keys()) if 'coretemp' in k]:
|
|
||||||
sensor_temps.extend(chip_temps[chip])
|
|
||||||
for chip in sorted(chip_temps.keys()):
|
|
||||||
if 'coretemp' not in chip:
|
|
||||||
sensor_temps.extend(chip_temps[chip])
|
|
||||||
|
|
||||||
# Wrap columns as needed
|
|
||||||
screen_size = shutil.get_terminal_size()
|
|
||||||
rows = screen_size.lines - 1
|
|
||||||
if len(sensor_temps) > rows and screen_size.columns > 55*2:
|
|
||||||
sensor_temps = list(itertools.zip_longest(
|
|
||||||
sensor_temps[:rows], sensor_temps[rows:], fillvalue=''))
|
|
||||||
sensor_temps = [join_columns(a, b) for a, b in sensor_temps]
|
|
||||||
|
|
||||||
# Print data
|
|
||||||
if sensor_temps:
|
|
||||||
for line in sensor_temps:
|
|
||||||
print_standard(line)
|
|
||||||
else:
|
|
||||||
if '--nocolor' in sys.argv:
|
|
||||||
print_standard('WARNING: No sensors found')
|
|
||||||
print_standard('\nPlease monitor temps manually')
|
|
||||||
else:
|
|
||||||
print_warning('WARNING: No sensors found')
|
|
||||||
print_standard('\nPlease monitor temps manually')
|
|
||||||
|
|
||||||
# Done
|
|
||||||
sensors.cleanup()
|
|
||||||
exit_script()
|
|
||||||
except SystemExit:
|
|
||||||
sensors.cleanup()
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
sensors.cleanup()
|
|
||||||
major_exception()
|
|
||||||
|
|
||||||
|
|
|
||||||
37
.bin/Scripts/hw-sensors-monitor
Executable file
37
.bin/Scripts/hw-sensors-monitor
Executable file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#!/bin/python3
|
||||||
|
#
|
||||||
|
## Wizard Kit: Sensor monitoring tool
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Init
|
||||||
|
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
||||||
|
sys.path.append(os.getcwd())
|
||||||
|
from functions.sensors import *
|
||||||
|
from functions.tmux import *
|
||||||
|
init_global_vars()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
background = False
|
||||||
|
try:
|
||||||
|
if len(sys.argv) > 1 and os.path.exists(sys.argv[1]):
|
||||||
|
background = True
|
||||||
|
monitor_file = sys.argv[1]
|
||||||
|
monitor_pane = None
|
||||||
|
else:
|
||||||
|
result = run_program(['mktemp'])
|
||||||
|
monitor_file = result.stdout.decode().strip()
|
||||||
|
if not background:
|
||||||
|
monitor_pane = tmux_split_window(
|
||||||
|
percent=1, vertical=True, watch=monitor_file)
|
||||||
|
cmd = ['tmux', 'resize-pane', '-Z', '-t', monitor_pane]
|
||||||
|
run_program(cmd, check=False)
|
||||||
|
monitor_sensors(monitor_pane, monitor_file)
|
||||||
|
exit_script()
|
||||||
|
except SystemExit:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
major_exception()
|
||||||
|
|
||||||
|
# vim: sts=2 sw=2 ts=2
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
ENABLED_OPEN_LOGS = False
|
ENABLED_OPEN_LOGS = False
|
||||||
ENABLED_TICKET_NUMBERS = False
|
ENABLED_TICKET_NUMBERS = False
|
||||||
ENABLED_UPLOAD_DATA = True
|
ENABLED_UPLOAD_DATA = True
|
||||||
|
HW_OVERRIDES_FORCED = False
|
||||||
|
HW_OVERRIDES_LIMITED = True # If True this disables HW_OVERRIDE_FORCED
|
||||||
|
|
||||||
# STATIC VARIABLES (also used by BASH and BATCH files)
|
# STATIC VARIABLES (also used by BASH and BATCH files)
|
||||||
## NOTE: There are no spaces around the = for easier parsing in BASH and BATCH
|
## NOTE: There are no spaces around the = for easier parsing in BASH and BATCH
|
||||||
|
|
|
||||||
|
|
@ -139,3 +139,5 @@ if __name__ == '__main__':
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
major_exception()
|
major_exception()
|
||||||
|
|
||||||
|
# vim: sts=4 sw=4 ts=4
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,6 @@ if __name__ == '__main__':
|
||||||
answer_reset_browsers = ask(
|
answer_reset_browsers = ask(
|
||||||
'Reset browsers to safe defaults first?')
|
'Reset browsers to safe defaults first?')
|
||||||
if global_vars['OS']['Version'] == '10':
|
if global_vars['OS']['Version'] == '10':
|
||||||
#answer_config_classicshell = ask('Configure ClassicShell?')
|
|
||||||
#answer_config_explorer_user = ask('Configure Explorer?')
|
|
||||||
answer_config_classicshell = True
|
answer_config_classicshell = True
|
||||||
answer_config_explorer_user = True
|
answer_config_explorer_user = True
|
||||||
|
|
||||||
|
|
@ -95,3 +93,5 @@ if __name__ == '__main__':
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
major_exception()
|
major_exception()
|
||||||
|
|
||||||
|
# vim: sts=4 sw=4 ts=4
|
||||||
|
|
|
||||||
|
|
@ -32,42 +32,6 @@ menuentry "Linux" {
|
||||||
submenuentry "Linux (CLI)" {
|
submenuentry "Linux (CLI)" {
|
||||||
add_options "loglevel=4 nomodeset nox"
|
add_options "loglevel=4 nomodeset nox"
|
||||||
}
|
}
|
||||||
submenuentry "Linux (Mac CLI)" {
|
|
||||||
add_options "loglevel=5 nomodeset nox"
|
|
||||||
}
|
|
||||||
submenuentry "Linux (MacBook9,1)" {
|
|
||||||
add_options "loglevel=5 intremap=nosid noacpi nomodeset"
|
|
||||||
}
|
|
||||||
submenuentry "Linux (MacBookAir5,2)" {
|
|
||||||
add_options "loglevel=5 intremap=off"
|
|
||||||
}
|
|
||||||
submenuentry "Linux (MacBookAir6,x)" {
|
|
||||||
add_options "loglevel=5 libata.force=1:noncq"
|
|
||||||
}
|
|
||||||
submenuentry "Linux (MacBookPro7,1)" {
|
|
||||||
add_options "loglevel=5 acpi_osi=! acpi_osi="Darwin" intremap=off nomodeset"
|
|
||||||
}
|
|
||||||
submenuentry "Linux (MacBookPro10,x)" {
|
|
||||||
add_options "loglevel=5 noapic"
|
|
||||||
}
|
|
||||||
submenuentry "Linux (MacBookPro11,x)" {
|
|
||||||
add_options "loglevel=5 acpi_osi="
|
|
||||||
}
|
|
||||||
submenuentry "Linux (Mac Generic Fix 1)" {
|
|
||||||
add_options "loglevel=5 acpi=force irqpoll noapic"
|
|
||||||
}
|
|
||||||
submenuentry "Linux (Mac Generic Fix 2)" {
|
|
||||||
add_options "loglevel=5 acpi=off"
|
|
||||||
}
|
|
||||||
submenuentry "Linux (Mac Generic Fix 3)" {
|
|
||||||
add_options "loglevel=5 acpi_osi=! acpi_osi="Darwin""
|
|
||||||
}
|
|
||||||
submenuentry "Linux (Mac Generic Fix 4)" {
|
|
||||||
add_options "loglevel=5 add_efi_memmap"
|
|
||||||
}
|
|
||||||
submenuentry "Linux (DEBUG)" {
|
|
||||||
add_options "loglevel=7 nomodeset nox"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#UFD#menuentry "WindowsPE" {
|
#UFD#menuentry "WindowsPE" {
|
||||||
#UFD# ostype windows
|
#UFD# ostype windows
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ bindsym $mod+d exec "urxvt -title 'Hardware Diagnostics' -e hw-diags"
|
||||||
bindsym $mod+f exec "thunar ~"
|
bindsym $mod+f exec "thunar ~"
|
||||||
bindsym $mod+i exec "hardinfo"
|
bindsym $mod+i exec "hardinfo"
|
||||||
bindsym $mod+m exec "urxvt -title 'Mount All Volumes' -e mount-all-volumes gui"
|
bindsym $mod+m exec "urxvt -title 'Mount All Volumes' -e mount-all-volumes gui"
|
||||||
bindsym $mod+s exec "urxvt -title 'Hardware Diagnostics' -e hw-diags quick"
|
bindsym $mod+s exec "urxvt -title 'Hardware Diagnostics' -e hw-diags --quick"
|
||||||
bindsym $mod+t exec "urxvt -e zsh -c 'tmux new-session -A -t general; zsh'"
|
bindsym $mod+t exec "urxvt -e zsh -c 'tmux new-session -A -t general; zsh'"
|
||||||
bindsym $mod+v exec "urxvt -title 'Hardware Sensors' -e watch -c -n1 -t hw-sensors"
|
bindsym $mod+v exec "urxvt -title 'Hardware Sensors' -e watch -c -n1 -t hw-sensors"
|
||||||
bindsym $mod+w exec "firefox"
|
bindsym $mod+w exec "firefox"
|
||||||
|
|
|
||||||
|
|
@ -324,7 +324,7 @@
|
||||||
</keybind>
|
</keybind>
|
||||||
<keybind key="W-s">
|
<keybind key="W-s">
|
||||||
<action name="Execute">
|
<action name="Execute">
|
||||||
<command>urxvt -title "Hardware Diagnostics" -e hw-diags quick</command>
|
<command>urxvt -title "Hardware Diagnostics" -e hw-diags --quick</command>
|
||||||
</action>
|
</action>
|
||||||
</keybind>
|
</keybind>
|
||||||
<keybind key="W-t">
|
<keybind key="W-t">
|
||||||
|
|
|
||||||
|
|
@ -92,3 +92,6 @@ else
|
||||||
cbatticon --hide-notification &
|
cbatticon --hide-notification &
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Prevent Xorg from being killed by .zlogin
|
||||||
|
touch "/tmp/x_ok"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,19 @@ if [ "$(fgconsole 2>/dev/null)" -eq "1" ]; then
|
||||||
|
|
||||||
# Start X or HW-diags
|
# Start X or HW-diags
|
||||||
if ! fgrep -q "nox" /proc/cmdline; then
|
if ! fgrep -q "nox" /proc/cmdline; then
|
||||||
|
# Kill Xorg after 30 seconds if it doesn't fully initialize
|
||||||
|
(sleep 30s; if ! [[ -f "/tmp/x_ok" ]]; then pkill '(Xorg|startx)'; fi) &
|
||||||
|
|
||||||
|
# Try starting X
|
||||||
startx >/dev/null
|
startx >/dev/null
|
||||||
|
|
||||||
|
# Run Hw-Diags CLI if necessary
|
||||||
|
if ! [[ -f "/tmp/x_ok" ]]; then
|
||||||
|
echo "There was an issue starting Xorg, starting CLI interface..."
|
||||||
|
sleep 2s
|
||||||
|
hw-diags --cli
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
hw-diags cli
|
hw-diags --cli
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,19 @@ LABEL wk_sys_linux_extras
|
||||||
TEXT HELP
|
TEXT HELP
|
||||||
Show extra Linux options
|
Show extra Linux options
|
||||||
ENDTEXT
|
ENDTEXT
|
||||||
MENU LABEL Linux (Extras)
|
MENU LABEL Linux (i3)
|
||||||
KERNEL vesamenu.c32
|
LINUX boot/x86_64/vmlinuz
|
||||||
APPEND boot/syslinux/wk_sys_linux_extras.cfg
|
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
||||||
|
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=3 i3
|
||||||
|
SYSAPPEND 3
|
||||||
|
|
||||||
|
LABEL wk_linux_cli
|
||||||
|
TEXT HELP
|
||||||
|
A live Linux environment (CLI)
|
||||||
|
* HW diagnostics, file-based backups, data recovery, etc
|
||||||
|
ENDTEXT
|
||||||
|
MENU LABEL Linux (CLI)
|
||||||
|
LINUX boot/x86_64/vmlinuz
|
||||||
|
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
||||||
|
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram nox nomodeset
|
||||||
|
SYSAPPEND 3
|
||||||
|
|
|
||||||
|
|
@ -1,198 +0,0 @@
|
||||||
INCLUDE boot/syslinux/wk_head.cfg
|
|
||||||
|
|
||||||
LABEL wk_linux
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=3
|
|
||||||
|
|
||||||
LABEL wk_linux_i3
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment (i3)
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (i3)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=3 i3
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
LABEL wk_linux_cli
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment (CLI)
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (CLI)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=4 nomodeset nox
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
LABEL wk_linux_mac_generic
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (Mac)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
LABEL wk_linux_mac_cli
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (Mac CLI)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 nomodeset nox reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
MENU SEPARATOR
|
|
||||||
|
|
||||||
LABEL wk_linux_macbook52
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* WARNING System will be limited to one CPU/thread
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (MacBook5,2)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 acpi=off irqpoll maxcpus=1 noapic reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
LABEL wk_linux_macbook91
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (MacBook9,1)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 intremap=nosid noacpi nomodeset reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
MENU SEPARATOR
|
|
||||||
|
|
||||||
LABEL wk_linux_macbookair52
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (MacBookAir5,2)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 intremap=off reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
LABEL wk_linux_macbookair6_
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* WARNING Drive I/O performance will be impacted
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (MacBookAir6,x)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 libata.force=1:noncq reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
MENU SEPARATOR
|
|
||||||
|
|
||||||
LABEL wk_linux_macbookpro71
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (MacBookPro7,1)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 acpi_osi=! acpi_osi="Darwin" intremap=off nomodeset reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
LABEL wk_linux_macbookpro10_
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (MacBookPro10,x)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 noapic reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
LABEL wk_linux_macbookpro11_
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (MacBookPro11,x)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 acpi_osi= reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
MENU SEPARATOR
|
|
||||||
|
|
||||||
LABEL wk_linux_mac_misc1
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (Misc Mac Fix 1)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 acpi=force irqpoll noapic reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
LABEL wk_linux_mac_misc2
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (Misc Mac Fix 2)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 acpi=off reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
LABEL wk_linux_mac_misc3
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (Misc Mac Fix 3)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=5 acpi_osi=! acpi_osi="Darwin" reboot=pci
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
MENU SEPARATOR
|
|
||||||
|
|
||||||
LABEL wk_linux_debug
|
|
||||||
TEXT HELP
|
|
||||||
A live Linux environment
|
|
||||||
* HW diagnostics, file-based backups, data recovery, etc
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Linux (DEBUG)
|
|
||||||
LINUX boot/x86_64/vmlinuz
|
|
||||||
INITRD boot/intel_ucode.img,boot/amd_ucode.img,boot/x86_64/archiso.img
|
|
||||||
APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% copytoram loglevel=7 nomodeset nox
|
|
||||||
SYSAPPEND 3
|
|
||||||
|
|
||||||
MENU SEPARATOR
|
|
||||||
|
|
||||||
LABEL wk_return
|
|
||||||
TEXT HELP
|
|
||||||
Show Return to the main menu
|
|
||||||
ENDTEXT
|
|
||||||
MENU LABEL Main Menu
|
|
||||||
KERNEL vesamenu.c32
|
|
||||||
APPEND boot/syslinux/wk_sys.cfg
|
|
||||||
14
Build Linux
14
Build Linux
|
|
@ -170,13 +170,15 @@ function update_live_env() {
|
||||||
# Memtest86
|
# Memtest86
|
||||||
mkdir -p "$LIVE_DIR/EFI/memtest86/Benchmark"
|
mkdir -p "$LIVE_DIR/EFI/memtest86/Benchmark"
|
||||||
mkdir -p "$TEMP_DIR/memtest86"
|
mkdir -p "$TEMP_DIR/memtest86"
|
||||||
curl -Lo "$TEMP_DIR/memtest86/memtest86.iso.tar.gz" "https://www.memtest86.com/downloads/memtest86-iso.tar.gz"
|
curl -Lo "$TEMP_DIR/memtest86/memtest86-usb.zip" "https://www.memtest86.com/downloads/memtest86-usb.zip"
|
||||||
tar xvf "$TEMP_DIR/memtest86/memtest86.iso.tar.gz" -C "$TEMP_DIR/memtest86"
|
7z e "$TEMP_DIR/memtest86/memtest86-usb.zip" -o"$TEMP_DIR/memtest86" "memtest86-usb.img"
|
||||||
7z x "$TEMP_DIR/memtest86"/*.iso -o"$TEMP_DIR/memtest86"
|
7z e "$TEMP_DIR/memtest86/memtest86-usb.img" -o"$TEMP_DIR/memtest86" "MemTest86.img"
|
||||||
mv "$TEMP_DIR/memtest86/EFI/BOOT/BLACKLIS.CFG" "$LIVE_DIR/EFI/memtest86/blacklist.cfg"
|
7z x "$TEMP_DIR/memtest86/MemTest86.img" -o"$TEMP_DIR/memtest86"
|
||||||
|
rm "$TEMP_DIR/memtest86/EFI/BOOT/BOOTIA32.EFI"
|
||||||
mv "$TEMP_DIR/memtest86/EFI/BOOT/BOOTX64.EFI" "$LIVE_DIR/EFI/memtest86/memtestx64.efi"
|
mv "$TEMP_DIR/memtest86/EFI/BOOT/BOOTX64.EFI" "$LIVE_DIR/EFI/memtest86/memtestx64.efi"
|
||||||
mv "$TEMP_DIR/memtest86/EFI/BOOT/MT86.PNG" "$LIVE_DIR/EFI/memtest86/mt86.png"
|
for f in "$TEMP_DIR/memtest86/EFI/BOOT"/* "help"/* license.rtf; do
|
||||||
mv "$TEMP_DIR/memtest86/EFI/BOOT/UNIFONT.BIN" "$LIVE_DIR/EFI/memtest86/unifont.bin"
|
mv "$f" "$LIVE_DIR/EFI/memtest86"/
|
||||||
|
done
|
||||||
|
|
||||||
# build.sh
|
# build.sh
|
||||||
if ! grep -iq 'wizardkit additions' "$LIVE_DIR/build.sh"; then
|
if ! grep -iq 'wizardkit additions' "$LIVE_DIR/build.sh"; then
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue