Systemd/test/create-sys-script.py
Zbigniew Jędrzejewski-Szmek 11a1589223 tree-wide: drop license boilerplate
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.

I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
2018-04-06 18:58:55 +02:00

180 lines
4.9 KiB
Python
Executable file

#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1+
OUTFILE_HEADER = """#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1+
#
# create-sys-script.py
#
# (C) 2017 Canonical Ltd.
# Author: Dan Streetman <dan.streetman@canonical.com>
"""
# Use this only to (re-)create the test/sys-script.py script,
# after adding or modifying anything in the test/sys/ directory
import os, sys
import stat
import tempfile
import filecmp
import subprocess
OUTFILE_MODE = 0o775
OUTFILE_FUNCS = r"""
import os, sys
import shutil
def d(path, mode):
os.mkdir(path, mode)
def l(path, src):
os.symlink(src, path)
def f(path, mode, contents):
with open(path, "wb") as f:
f.write(contents)
os.chmod(path, mode)
"""
OUTFILE_MAIN = """
if len(sys.argv) < 2:
exit("Usage: {} <target dir>".format(sys.argv[0]))
if not os.path.isdir(sys.argv[1]):
exit("Target dir {} not found".format(sys.argv[1]))
os.chdir(sys.argv[1])
if os.path.exists('sys'):
shutil.rmtree('sys')
"""
def handle_dir(outfile, path):
m = os.lstat(path).st_mode & 0o777
outfile.write(f"d('{path}', {m:#o})\n")
def handle_link(outfile, path):
src = os.readlink(path)
outfile.write(f"l('{path}', '{src}')\n")
def escape_single_quotes(b):
# remove the b'' wrapping each line repr
r = repr(b)[2:-1]
# python escapes all ' only if there are ' and " in the string
if '"' not in r:
r = r.replace("'", r"\'")
# return line with all ' escaped
return r
def handle_file(outfile, path):
m = os.lstat(path).st_mode & 0o777
with open(path, "rb") as f:
b = f.read()
if b.count(b"\n") > 1:
r = "\n".join( escape_single_quotes(l) for l in b.split(b"\n") )
r = f"b'''{r}'''"
else:
r = repr(b)
outfile.write(f"f('{path}', {m:#o}, {r})\n")
def process_sysdir(outfile):
for (dirpath, dirnames, filenames) in os.walk('sys'):
handle_dir(outfile, dirpath)
for d in dirnames:
path = os.path.join(dirpath, d)
if stat.S_ISLNK(os.lstat(path).st_mode):
handle_link(outfile, path)
for f in filenames:
path = os.path.join(dirpath, f)
mode = os.lstat(path).st_mode
if stat.S_ISLNK(mode):
handle_link(outfile, path)
elif stat.S_ISREG(mode):
handle_file(outfile, path)
def verify_dir(tmpd, path_a):
path_b = os.path.join(tmpd, path_a)
mode_a = os.lstat(path_a).st_mode
mode_b = os.lstat(path_b).st_mode
if not stat.S_ISDIR(mode_b):
raise Exception("Not directory")
if (mode_a & 0o777) != (mode_b & 0o777):
raise Exception("Permissions mismatch")
def verify_link(tmpd, path_a):
path_b = os.path.join(tmpd, path_a)
if not stat.S_ISLNK(os.lstat(path_b).st_mode):
raise Exception("Not symlink")
if os.readlink(path_a) != os.readlink(path_b):
raise Exception("Symlink dest mismatch")
def verify_file(tmpd, path_a):
path_b = os.path.join(tmpd, path_a)
mode_a = os.lstat(path_a).st_mode
mode_b = os.lstat(path_b).st_mode
if not stat.S_ISREG(mode_b):
raise Exception("Not file")
if (mode_a & 0o777) != (mode_b & 0o777):
raise Exception("Permissions mismatch")
if not filecmp.cmp(path_a, path_b, shallow=False):
raise Exception("File contents mismatch")
def verify_script(tmpd):
any = False
for (dirpath, dirnames, filenames) in os.walk("sys"):
any = True
try:
path = dirpath
verify_dir(tmpd, path)
for d in dirnames:
path = os.path.join(dirpath, d)
if stat.S_ISLNK(os.lstat(path).st_mode):
verify_link(tmpd, path)
for f in filenames:
path = os.path.join(dirpath, f)
mode = os.lstat(path).st_mode
if stat.S_ISLNK(mode):
verify_link(tmpd, path)
elif stat.S_ISREG(mode):
verify_file(tmpd, path)
except Exception:
print(f'FAIL on "{path}"', file=sys.stderr)
raise
if not any:
exit('Nothing found!')
if __name__ == "__main__":
if len(sys.argv) < 2:
exit('Usage: create-sys-script.py /path/to/test/')
outfile = os.path.abspath(os.path.dirname(sys.argv[0]) + '/sys-script.py')
print(f'Creating {outfile} using contents of {sys.argv[1]}/sys')
os.chdir(sys.argv[1])
with open(outfile, "w") as f:
os.chmod(outfile, OUTFILE_MODE)
f.write(OUTFILE_HEADER.replace(os.path.basename(sys.argv[0]),
os.path.basename(outfile)))
f.write(OUTFILE_FUNCS)
f.write(OUTFILE_MAIN)
process_sysdir(f)
with tempfile.TemporaryDirectory() as tmpd:
print(f'Recreating sys/ using {outfile} at {tmpd}')
subprocess.check_call([outfile, tmpd])
verify_script(tmpd)
print(f'Verification successful, {outfile} is correct')