42 lines
2.2 KiB
Python
42 lines
2.2 KiB
Python
"""Read-only deployed source and health verification; emits no network or device identity."""
|
|
import hashlib
|
|
import json
|
|
import shlex
|
|
from remote_support import ROOT, connect, execute
|
|
|
|
FILES = ['app/main.py', 'app/mobile/session.py', 'app/mobile/protocol.py', 'app/mobile/control.py',
|
|
'app/mobile/wifi.py', 'app/static/index.html', 'app/static/views/device.js', 'FEATURE_UPDATED_AT']
|
|
|
|
|
|
def main():
|
|
client, fields = connect()
|
|
try:
|
|
code, _, _ = execute(client, 'command -v python3 >/dev/null && command -v systemctl >/dev/null')
|
|
if code: raise RuntimeError('Remote tools unavailable')
|
|
program = '''import hashlib,json,urllib.request
|
|
from pathlib import Path
|
|
names=NAMES
|
|
digests={n:hashlib.sha256((Path('/opt/matrix-screen-controller')/n).read_bytes()).hexdigest() for n in names}
|
|
s=json.load(urllib.request.urlopen('http://127.0.0.1:8080/api/status',timeout=10))
|
|
d=s['screen']['driver_status']
|
|
print(json.dumps({'digests':digests,'health':{'mobile_available':s['mobile']['available'],
|
|
'active_transport':s['mobile'].get('active_transport'),'driver_available':s['screen']['driver_available'],
|
|
'driver_running':d.get('running'),'actual_refresh_rate_hz':d.get('actual_refresh_rate_hz'),
|
|
'deadline_misses':d.get('deadline_misses'),'driver_error_absent':not d.get('last_error'),
|
|
'feature_updated_at':s['service']['feature_updated_at'],'software_version':s['service']['software_version']}}))
|
|
'''.replace('NAMES', repr(FILES))
|
|
code, output, _ = execute(client, 'python3 -c ' + shlex.quote(program), password=fields['密码'])
|
|
if code: raise RuntimeError('Deployment verification failed')
|
|
result = json.loads(output)
|
|
expected = {n: hashlib.sha256((ROOT / '核桃派软件源代码' / n).read_bytes()).hexdigest() for n in FILES}
|
|
if result['digests'] != expected: raise RuntimeError('Deployed source differs from current source')
|
|
code, _, _ = execute(client, 'systemctl is-active --quiet matrix-screen-controller.service')
|
|
if code: raise RuntimeError('Main service is not active')
|
|
print(json.dumps(dict(source_matches=True, service_active=True, **result['health'])))
|
|
finally:
|
|
client.close()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|