更新
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
BASE = '/www/backup/txiaw-mysql-fix-20260831'
|
||||
STAGE = BASE + '/stage'
|
||||
WEB = '/www/wwwroot/www.txiaw.com'
|
||||
NGINX = '/www/server/panel/vhost/nginx'
|
||||
BIN = '/www/server/nginx/sbin/nginx'
|
||||
PHP = '/www/server/php/56/bin/php'
|
||||
|
||||
def run(args):
|
||||
subprocess.run(args, check=True, timeout=20)
|
||||
|
||||
def atomic_copy(src, dst, metadata=None):
|
||||
info = metadata or os.stat(src)
|
||||
fd, tmp = tempfile.mkstemp(prefix='.txiaw-repair-', suffix='.tmp', dir=os.path.dirname(dst))
|
||||
try:
|
||||
with os.fdopen(fd, 'wb') as target, open(src, 'rb') as source:
|
||||
shutil.copyfileobj(source, target)
|
||||
target.flush()
|
||||
os.fsync(target.fileno())
|
||||
os.chmod(tmp, stat.S_IMODE(info.st_mode))
|
||||
os.chown(tmp, info.st_uid, info.st_gid)
|
||||
os.replace(tmp, dst)
|
||||
finally:
|
||||
if os.path.exists(tmp):
|
||||
os.unlink(tmp)
|
||||
|
||||
manifest = json.load(open(STAGE + '/baseline.json'))
|
||||
for item in manifest:
|
||||
data = open(item['remote'], 'rb').read()
|
||||
if hashlib.sha256(data).hexdigest() != item['sha256']:
|
||||
raise RuntimeError('Source changed since inspection: ' + item['remote'])
|
||||
shutil.copy2(item['remote'], BASE + '/originals/' + item['backup'])
|
||||
os.chmod(BASE + '/originals/' + item['backup'], 0o600)
|
||||
|
||||
for name in ['HomeRequestProtection.php', 'index.php', 'test_home_guard.php']:
|
||||
run([PHP, '-l', STAGE + '/' + name])
|
||||
run([PHP, STAGE + '/test_home_guard.php'])
|
||||
|
||||
changes = [
|
||||
('HomeRequestProtection.php', WEB + '/Lib/HomeRequestProtection.php', None),
|
||||
('index.php', WEB + '/index.php', 'original-index.php'),
|
||||
('txiaw-home-protection-http.inc', NGINX + '/txiaw-home-protection-http.inc', None),
|
||||
('txiaw-home-protection-server.inc', NGINX + '/txiaw-home-protection-server.inc', None),
|
||||
('www.txiaw.com.conf', NGINX + '/www.txiaw.com.conf', 'original-www.txiaw.com.conf'),
|
||||
]
|
||||
for source, target, backup in changes:
|
||||
if backup is None and os.path.exists(target):
|
||||
raise RuntimeError('Refusing to overwrite unexpected file: ' + target)
|
||||
|
||||
installed = []
|
||||
metadata = {}
|
||||
try:
|
||||
for source, target, backup in changes:
|
||||
metadata[target] = os.stat(target) if backup else None
|
||||
if not backup:
|
||||
os.chmod(STAGE + '/' + source, 0o644)
|
||||
atomic_copy(STAGE + '/' + source, target, metadata[target])
|
||||
installed.append((target, backup))
|
||||
run([BIN, '-t'])
|
||||
run([BIN, '-s', 'reload'])
|
||||
except Exception:
|
||||
for target, backup in reversed(installed):
|
||||
if backup:
|
||||
atomic_copy(BASE + '/originals/' + backup, target, metadata[target])
|
||||
else:
|
||||
os.unlink(target)
|
||||
run([BIN, '-t'])
|
||||
raise
|
||||
|
||||
json.dump({'files': [p for p, _ in installed], 'status': 'installed'}, open(BASE + '/guard-installed.json', 'w'), indent=2)
|
||||
print('GUARD_DEPLOYED; PHP guard passed; nginx configuration passed and gracefully reloaded.', flush=True)
|
||||
Reference in New Issue
Block a user