Add options to install libraries for bianry

This commit is contained in:
Mikhail Gordeev 2023-02-14 02:16:57 +03:00
parent 89e331224d
commit aa2756bae2
3 changed files with 75 additions and 19 deletions

View File

@ -70,7 +70,9 @@ class Distroless:
self.file_lists = dd.get("file-lists", []) self.file_lists = dd.get("file-lists", [])
self.files = dd.get("files", []) self.files = dd.get("files", [])
self.library_files = dd.get("library-files", [])
self.packages = dd.get("packages", []) self.packages = dd.get("packages", [])
self.library_packages = dd.get("library-packages", [])
self.exclude_regexes = dd.get("exclude-regexes", []) self.exclude_regexes = dd.get("exclude-regexes", [])
self.builder_install_packages = dd.get("builder-install-packages") self.builder_install_packages = dd.get("builder-install-packages")
@ -326,14 +328,14 @@ class DockerBuilder:
] ]
) )
files_options = [] options = []
file_lists_options = []
packages_options = []
if distroless.files: if distroless.files:
files_options = ["-f"] + distroless.files options += ["-f"] + distroless.files
if distroless.library_files:
options += ["--library-files"] + distroless.library_files
if file_lists := distroless.file_lists: if file_lists := distroless.file_lists:
file_lists_options = ["-l"] options += ["-l"]
file_lists_options.extend([f"file-lists/{f}" for f in file_lists]) options += [f"file-lists/{f}" for f in file_lists]
for file_list in file_lists: for file_list in file_lists:
run( run(
[ [
@ -345,7 +347,9 @@ class DockerBuilder:
] ]
) )
if distroless.packages: if distroless.packages:
packages_options = ["-p"] + distroless.packages options += ["-p"] + distroless.packages
if distroless.library_packages:
options += ["--library-packages"] + distroless.library_packages
run( run(
[ [
@ -356,9 +360,7 @@ class DockerBuilder:
"add", "add",
"--clean", "--clean",
] ]
+ files_options + options
+ file_lists_options
+ packages_options
) )
exclude_regexes_options = [] exclude_regexes_options = []

View File

@ -3,7 +3,7 @@ FROM {{ registry }}{{ alt_image }}:{{ branch }}
MAINTAINER alt-cloud MAINTAINER alt-cloud
RUN echo %_excludedocs 1 >> /etc/rpm/macros RUN echo %_excludedocs 1 >> /etc/rpm/macros
{{ install_pakages("python3") }} {{ install_pakages("python3", "glibc-utils") }}
WORKDIR /usr/src/distroless WORKDIR /usr/src/distroless
RUN mkdir file-lists RUN mkdir file-lists
RUN useradd -m nonroot RUN useradd -m nonroot

View File

@ -15,16 +15,20 @@ class DL:
def __init__(self, dl_file): def __init__(self, dl_file):
self.dl_file = Path(dl_file) self.dl_file = Path(dl_file)
def add(self, files, file_lists, packages, is_glob=True): def add(self, files, file_lists, packages, is_glob=True, follow_symlink=True):
def ensuere_one_endl(s): def write(dl_file, file):
return s.rstrip("\n") + "\n" file = file.rstrip("\n")
dl_file.write(file + "\n")
path = Path(file)
if follow_symlink and path.is_symlink():
dl_file.write(path.resolve().as_posix() + "\n")
def write_globs(is_glob, source, dl_file): def write_globs(is_glob, source, dl_file):
if is_glob: if is_glob:
for file in glob.glob(source.rstrip("\n")): for file in glob.glob(source.rstrip("\n")):
dl_file.write(ensuere_one_endl(file)) write(dl_file, file)
else: else:
dl_file.write(ensuere_one_endl(source)) write(dl_file, file)
with open(self.dl_file, "a") as dl_file: with open(self.dl_file, "a") as dl_file:
for file in files: for file in files:
@ -39,7 +43,7 @@ class DL:
for line in proc.stdout.decode().splitlines(): for line in proc.stdout.decode().splitlines():
state, filename = line.split(maxsplit=1) state, filename = line.split(maxsplit=1)
if state == "normal": if state == "normal":
dl_file.write(ensuere_one_endl(filename)) write(dl_file, filename)
def tar(self, outfile, regexes): def tar(self, outfile, regexes):
def filter(tarinfo): def filter(tarinfo):
@ -56,6 +60,31 @@ class DL:
self.dl_file.unlink(missing_ok=True) self.dl_file.unlink(missing_ok=True)
def library_files(binaries):
files = set()
for binary in binaries:
ldd = subprocess.run(["ldd", binary], stdout=subprocess.PIPE)
ldd.check_returncode()
for line in ldd.stdout.decode().splitlines():
if match := re.match(r".*=>\s*(?P<file>\S+)", line):
files.add(match.groupdict()["file"])
return list(files)
def library_packages(binaries):
packages = set()
for file in library_files(binaries):
rpm = subprocess.run(
["rpm", "-qf", file, "--queryformat", r"%{NAME}\n"],
stdout=subprocess.PIPE,
)
rpm.check_returncode()
packages.add(rpm.stdout.decode().strip())
return list(packages)
def parse_args(): def parse_args():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter, formatter_class=argparse.ArgumentDefaultsHelpFormatter,
@ -71,7 +100,14 @@ def parse_args():
action="store_false", action="store_false",
default=True, default=True,
dest="glob", dest="glob",
help="clean before add", help="do not expand file names as globs",
)
parser_add.add_argument(
"--no-follow-symlink",
action="store_false",
default=True,
dest="follow_symlink",
help="do not add symlink destination with symlink",
) )
parser_add.add_argument( parser_add.add_argument(
"--clean", "--clean",
@ -92,6 +128,18 @@ def parse_args():
default=[], default=[],
help="adding file from file lists to the dl-file", help="adding file from file lists to the dl-file",
) )
parser_add.add_argument(
"--library-files",
nargs="+",
default=[],
help="adding library files for binaries to the the dl-file",
)
parser_add.add_argument(
"--library-packages",
nargs="+",
default=[],
help="adding library packages for binaries to the the dl-file",
)
parser_add.add_argument( parser_add.add_argument(
"-p", "-p",
"--packages", "--packages",
@ -127,7 +175,13 @@ def main():
if args.subparser_name == "add": if args.subparser_name == "add":
if args.clean: if args.clean:
dl.clean() dl.clean()
dl.add(args.files, args.file_lists, args.packages, args.glob) dl.add(
args.files + library_files(args.library_files),
args.file_lists,
args.packages + library_packages(args.library_packages),
args.glob,
args.follow_symlink,
)
elif args.subparser_name == "tar": elif args.subparser_name == "tar":
dl.tar(args.outfile, args.regexes) dl.tar(args.outfile, args.regexes)
elif args.subparser_name == "clean": elif args.subparser_name == "clean":