[Áp phích gốc]
Không có nhiều niềm vui, tôi đã viết một kịch bản để tính toán sự khác biệt và thực hiện lệnh khôi phục; Có khoảng 100 gói tham gia. Đáng buồn là việc hạ cấp của tôi không thành công vì nhiều gói không còn khả dụng :(
#!/usr/bin/env python
import sys, getopt, os
from datetime import datetime
datefmt = "%Y-%m-%d %H:%M:%S"
dry_run = True
try:
opts,args = getopt.getopt(sys.argv[1:],"y")
if not args:
raise Exception("no date specified")
elif len(args) == 1:
args.append("00:00:00") # default time
elif len(args) != 2:
raise Exception("unexpected arguments")
snapshot = datetime.strptime(" ".join(args),datefmt)
for opt,_ in opts:
if opt == "-y":
dry_run = False
else:
raise Exception("unsupported option %s"%opt)
except Exception as e:
print "error:",e
print "usage:",sys.argv[0],"[flags] YYYY-MM-DD [HH:MM:SS]"
print "flags: -y = for real; don\'t just show it, restore it"
sys.exit(1)
# work out what to do
history = {}
restore = set()
remove = set()
with open("/var/log/dpkg.log","r") as log:
for line in log:
date,time,action,line = line.split(None,3)
when = datetime.strptime("%s %s"%(date,time),datefmt)
package,ver = line.strip().split(None,1)
if when <= snapshot:
if action in ("upgrade","install"):
prev_ver,new_ver = ver.split()
history[package] = new_ver
elif action == "remove":
if package in history:
del history[package]
else:
print "(cannot remove %s)"%line
else:
if action == "install":
remove.add(package)
elif action == "upgrade":
if package in history:
restore.add(package)
elif package not in remove:
print "(cannot revert %s)"%line
elif action == "remove":
if package in history:
restore.add(package)
elif package in remove:
remove.remove(package)
else:
print "(cannot revert %s)"%line
# show what to do
for package in restore:
print "restore",package,history[package]
for package in remove:
print "remove",package
# do it
if not dry_run:
print "======"
def execute(cmd):
print cmd
os.system(cmd)
#execute("apt-get remove "+" ".join(remove))
execute("apt-get install "+" ".join("%s=%s"%(package,history[package]) for package in restore))