运维:固定虚拟PCI设备并补充过夜观察与电源策略
This commit is contained in:
1 parent
6f2ff67300
commit
65f92df8b7
42 files changed
+1705
No files matched your search
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Apply/query/restore power-menu policy via the existing PVE guest agent.
|
||||
|
||||
Uses the repository's existing PVE authentication. Never powers off/reboots a VM.
|
||||
"""
|
||||
import argparse
|
||||
import base64
|
||||
import json
|
||||
from pathlib import Path
|
||||
import runpy
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('action', choices=['apply', 'query', 'restore'])
|
||||
parser.add_argument('--vm', type=int, required=True, choices=[100, 101, 102])
|
||||
parser.add_argument('--user', help='Required for Linux guests')
|
||||
parser.add_argument('--evidence', type=Path, help='Save the guest-agent result as JSON')
|
||||
args = parser.parse_args()
|
||||
root = Path(__file__).resolve().parent
|
||||
api = runpy.run_path(str(root / 'pve_vm.py'))['api']
|
||||
ticket, csrf = runpy.run_path(str(root / 'pve_term_exec.py'))['login']()
|
||||
base = f'/api2/json/nodes/starhe/qemu/{args.vm}'
|
||||
if api(base + '/status/current', ticket=ticket).get('status') != 'running':
|
||||
raise SystemExit('Guest is not running; nothing changed')
|
||||
if args.vm == 100:
|
||||
source = (root / 'set-guest-power-policy.ps1').read_text(encoding='utf-8')
|
||||
source = "$ProgressPreference='SilentlyContinue'\n& {\n" + source + "\n} -Action " + args.action.capitalize()
|
||||
encoded = base64.b64encode(source.encode('utf-16le')).decode()
|
||||
command = ['powershell.exe', '-NoProfile', '-NonInteractive', '-EncodedCommand', encoded]
|
||||
else:
|
||||
if not args.user:
|
||||
parser.error('--user is required for Linux')
|
||||
source = (root / 'set-guest-power-policy.py').read_text(encoding='utf-8')
|
||||
command = ['python3', '-c', source, args.action, '--user', args.user]
|
||||
pid = api(base + '/agent/exec', json_body={'command': command}, ticket=ticket, csrf=csrf)['pid']
|
||||
for _ in range(60):
|
||||
time.sleep(1)
|
||||
result = api(base + f'/agent/exec-status?pid={pid}', ticket=ticket)
|
||||
if result.get('exited'):
|
||||
report = json.dumps({'vm': args.vm, **result}, ensure_ascii=True)
|
||||
if args.evidence:
|
||||
args.evidence.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.evidence.write_text(report + '\n', encoding='utf-8')
|
||||
print(report)
|
||||
if result.get('exitcode') or result.get('out-truncated') or result.get('err-truncated'):
|
||||
raise SystemExit(1)
|
||||
return
|
||||
raise SystemExit('Guest operation timed out; query before retrying')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in new issue
Block a user