blob: 71f166d5606afeec7338827a6038ce3a04765210 [file] [log] [blame]
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""The Package Size Reporting CLI entry point."""
import os
from chromite.lib import commandline
from chromite.lib import metrics_lib
from chromite.lib import portage_util
from chromite.utils import pformat
_PARTITION_NAMES = ["rootfs", "stateful"]
def _get_parser():
"""Create an argument parser for this script."""
parser = commandline.ArgumentParser(description=__doc__)
parser.add_argument(
"--root",
required=True,
type="str_path",
help="Specify the rootfs to investigate.",
)
parser.add_argument(
"--image-type",
help="Specify the type of image being investigated. "
"e.g. [base, dev, test]",
)
parser.add_argument(
"--partition-name",
choices=_PARTITION_NAMES,
help="Specify the partition name. " "e.g. [rootfs, stateful]",
)
parser.add_argument(
"packages",
nargs="*",
help="Names of packages to investigate. Must be "
"specified as category/package-version.",
)
return parser
def generate_package_size_report(
db, root, image_type, partition_name, installed_packages
):
"""Collect package sizes and generate a report."""
results = {}
package_sizes = portage_util.GeneratePackageSizes(
db, root, installed_packages
)
timestamp = metrics_lib.current_milli_time()
for package_cpv, size in package_sizes:
results[package_cpv] = size
metrics_lib.append_metrics_log(
timestamp,
"package_size.%s.%s.%s" % (image_type, partition_name, package_cpv),
metrics_lib.OP_GAUGE,
arg=size,
)
rootfs_stat = os.statvfs(root)
block_size = rootfs_stat.f_bsize
blocks_used = rootfs_stat.f_blocks - rootfs_stat.f_bfree
total_size = block_size * blocks_used
metrics_lib.append_metrics_log(
timestamp,
"total_size.%s.%s" % (image_type, partition_name),
metrics_lib.OP_GAUGE,
arg=total_size,
)
return {
"root": root,
"package_sizes": results,
"total_size": total_size,
"package_database_path": db.db_path,
"package_install_path": db.package_install_path,
}
def main(argv) -> None:
"""Find and report approximate size info for a particular built package."""
commandline.RunInsideChroot()
parser = _get_parser()
opts = parser.parse_args(argv)
opts.Freeze()
vdb = package_install_path = ""
if opts.partition_name == "stateful":
vdb = "var_overlay/db/pkg"
package_install_path = "dev_image"
db = portage_util.PortageDB(
root=opts.root, vdb=vdb, package_install_path=package_install_path
)
if opts.packages:
installed_packages = portage_util.GenerateInstalledPackages(
db, opts.root, opts.packages
)
else:
installed_packages = db.InstalledPackages()
results = generate_package_size_report(
db, opts.root, opts.image_type, opts.partition_name, installed_packages
)
print(pformat.json(results))