| workflow_payload |
name: Verify private memory restore mounts and abn name: Verify private memory restore mounts and abnormal cleanup with fixtures
"on":
workflow_dispatch:
inputs:
inspect_run:
description: Inspect only the fixed owned failure 27250; empty runs a new fixture
required: false
default: ''
jobs:
validate:
name: validate
runs-on: ubuntu-latest
if: github.repository == 'luoanwu/enterprise-platform'
steps:
- name: Verify fixed private fixture filesystems without changing production
run: |
set -eu
python3 <<'PY'
import ast,hashlib,json,os,pathlib,re,stat,subprocess
run=os.environ['GITHUB_RUN_ID'];sha=os.environ['GITHUB_SHA']
if not run.isdigit() or not re.fullmatch('[0-9a-f]{40}',sha):raise RuntimeError('FIXED_JOB_IDENTITY_REQUIRED')
inspect=os.environ.get('INSPECT_MEMORY_PROBE_RUN','')
if inspect:
if inspect!='27250':raise RuntimeError('ONLY_FIXED_OWNED_FAILURE_INSPECTION_ALLOWED')
prior=pathlib.Path('/var/lib/eios-r1-maintenance/memory-fs-probe-27250')
for name in ['run-memory-filesystem-probe.py','probe-memory-restore-filesystems.py','memory-restore-mounts.py']:
r=subprocess.run(['git','-c','safe.directory=/home/git/repositories/luoanwu/enterprise-platform.git','-C','/home/git/repositories/luoanwu/enterprise-platform.git','show','1d22f982b7393d24fe87092d756727acb96288a1:ops/gitea-r1/'+name],capture_output=True,timeout=30)
if r.returncode or hashlib.sha256((prior/name).read_bytes()).digest()!=hashlib.sha256(r.stdout).digest():raise RuntimeError('FIXED_FAILED_PROBE_SOURCE_REQUIRED')
p=prior/'normal/native.stderr'
for parent in [prior.parent,prior,prior/'normal']:
details=parent.lstat()
if not stat.S_ISDIR(details.st_mode) or details.st_uid!=0 or details.st_mode&0o077:raise RuntimeError('PRIVATE_FAILURE_ANCESTRY_REQUIRED')
details=p.lstat()
if not stat.S_ISREG(details.st_mode) or details.st_uid!=0 or details.st_nlink!=1 or details.st_mode&0o022 or details.st_size>262144:raise RuntimeError('PRIVATE_FIXED_FAILURE_LOG_REQUIRED')
raw=p.read_text();frames=[]
for name,line,function in re.findall(r'File "([^"]+)", line ([0-9]+), in ([A-Za-z_][A-Za-z0-9_]*)',raw):
frames.append({'file':pathlib.Path(name).name,'line':int(line),'function':function})
units={}
for mode in ['normal','kill']:
r=subprocess.run(['systemctl','show','eios-r1-memory-fs-'+mode+'-27250','--property=LoadState,ActiveState,ExecMainPID'],capture_output=True,text=True,timeout=20)
units[mode]=dict(line.split('=',1) for line in r.stdout.splitlines() if '=' in line)
mounts=[line for line in pathlib.Path('/proc/self/mountinfo').read_text().splitlines() if line.split()[4].startswith(str(prior)+'/')]
errors=re.findall(r'(?m)^([A-Za-z]+Error): \[Errno ([0-9]+)\]',raw)
report={'kind':'R1PrivateMemoryFilesystemFailureInspection','ci':{'runId':run,'sourceSha':sha},'failedRunId':'27250','failedSource':'1d22f982b7393d24fe87092d756727acb96288a1','logMetadata':{'mode':oct(stat.S_IMODE(details.st_mode)),'uid':details.st_uid,'bytes':details.st_size,'privateAncestorChainVerified':True},'frames':frames,'errors':[{'class':name,'errno':int(number)} for name,number in errors],'proc1MountNamespaceMentioned':"/proc/1/ns/mnt" in raw,'hostMountsUnderOwnedWork':len(mounts),'ownedUnitStates':units,'productionServicesChanged':False,'windowAdmissionGranted':False}
print('R1_MEMORY_FS_FAILURE_INSPECTION_JSON '+json.dumps(report));raise SystemExit(0)
work=pathlib.Path('/var/lib/eios-r1-maintenance')/('memory-fs-probe-'+run);work.mkdir(mode=0o700)
for name in ['probe-memory-restore-filesystems.py','memory-restore-mounts.py','memory-restore-layout.py','test-memory-restore-mounts.py','test-memory-restore-layout.py','window-support.py','run-memory-filesystem-probe.py']:
r=subprocess.run(['git','-c','safe.directory=/home/git/repositories/luoanwu/enterprise-platform.git','-c','core.hooksPath=/dev/null','-C','/home/git/repositories/luoanwu/enterprise-platform.git','show',sha+':ops/gitea-r1/'+name],capture_output=True,timeout=30)
if r.returncode:raise RuntimeError('FIXED_PRIVATE_FILESYSTEM_PROBE_SOURCE_REQUIRED')
ast.parse(r.stdout);(work/name).write_bytes(r.stdout)
for name in ['test-memory-restore-layout.py','test-memory-restore-mounts.py']:subprocess.run(['python3','-B',str(work/name)],check=True,timeout=30)
subprocess.run(['python3','-B',str(work/'run-memory-filesystem-probe.py')],check=True,timeout=300)
PY
shell: bash
env:
INSPECT_MEMORY_PROBE_RUN: ${{ inputs.inspect_run }}
timeout-minutes: "8"
permissions:
contents: read
... |