blob: 92e5e136d326b219dd35ae16d69ac3ff0c327b62 [file] [log] [blame]
# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Generate an HTML file containing license info for all installed packages.
Documentation on this script is also available here:
http://www.chromium.org/chromium-os/licensing-for-chromiumos-developers
End user (i.e. package owners) documentation is here:
http://www.chromium.org/chromium-os/licensing-for-chromiumos-package-owners
Usage:
For this script to work, you must have built the architecture
this is being run against, _after_ you've last run repo sync.
Otherwise, it will query newer source code and then fail to work on packages
that are out of date in your build.
Recommended build:
cros_sdk
export BOARD=x86-alex
sudo rm -rf /build/$BOARD
cd ~/trunk/src/scripts
# If you wonder why we need to build Chromium OS just to run
# `emerge -p -v virtual/target-os` on it, we don't.
# However, later we run ebuild unpack, and this will apply patches and run
# configure. Configure will fail due to aclocal macros missing in
# /build/x86-alex/usr/share/aclocal (those are generated during build).
# This will take about 10mn on a Z620.
./build_packages --board=$BOARD --nowithautotest --nowithtest --nowithdev
--nowithfactory
cd ~/trunk/chromite/licensing
# This removes left over packages from an earlier build that could cause
# conflicts.
eclean-$BOARD packages
%(prog)s [--debug] [--all-packages] --board $BOARD [-o o.html] 2>&1 | tee out
The workflow above is what you would do to generate a licensing file by hand
given a chromeos tree.
Note that building packages now creates a license.yaml fork in the package
which you can see with
qtbz2 -x -O /build/x86-alex/packages/dev-util/libc-bench-0.0.1-r8.tbz2 |
qxpak -x -O - license.yaml
This gets automatically installed in
/build/x86-alex/var/db/pkg/dev-util/libc-bench-0.0.1-r8/license.yaml
Unless you run with --generate, the script will now gather those license
bits and generate a license file from there.
License bits for each package are generated by default from
src/scripts/hooks/install/gen-package-licenses.sh which gets run automatically
by emerge as part of a package build (by running this script with
--hook /path/to/tmp/portage/build/tree/for/that/package
If license bits are missing, they are generated on the fly if you were running
with sudo. If you didn't use sudo, this on the fly late generation will fail
and act as a warning that your prebuilts were missing package build time
licenses.
You can check the licenses and/or generate a HTML file for a list of
packages using --package or -p:
%(prog)s --package "dev-libs/libatomic_ops-7.2d" --package
"net-misc/wget-1.14" --board $BOARD -o out.html
Note that you'll want to use --generate to force regeneration of the licensing
bits from a package source you may have just modified but not rebuilt.
If you want to check licensing against all ChromeOS packages, you should
run ./build_packages --board=$BOARD to build everything and then run
this script with --all-packages.
By default, when no package is specified, this script processes all
packages for $BOARD. The output HTML file is meant to update
http://src.chromium.org/viewvc/chrome/trunk/src/chrome/browser/resources/ +
chromeos/about_os_credits.html?view=log
(gclient config svn://svn.chromium.org/chrome/trunk/src)
For an example CL, see https://codereview.chromium.org/13496002/
The detailed process is listed below.
* Check out the branch you intend to generate the HTML file for. Use
the internal manifest for this purpose.
repo init -b <branch_name> -u <URL>
The list of branches (e.g. release-R33-5116.B) are available here:
https://chromium.googlesource.com/chromiumos/manifest/+refs
* Generate the HTML file by following the steps mentioned
previously. Check whether your changes are valid with:
bin/diff_license_html output.html-M33 output.html-M34
and review the diff.
* Update the about_os_credits.html in the svn repository. Create a CL
and upload it for review.
gcl change <change_name>
gcl upload <change_name>
When uploading, you may get a warning for file being too large to
upload. In this case, your CL can still be reviewed. Always include
the diff in your commit message so that the reviewers know what the
changes are. You can add reviewers on the review page by clicking on
"Edit issue". (A quick reference:
http://www.chromium.org/developers/quick-reference)
Make sure you click on 'Publish+Mail Comments' after adding reviewers
(the review URL looks like this https://codereview.chromium.org/183883018/ ).
* After receiving LGTMs, commit your change with 'gcl commit <change_name>'.
If you don't get this in before the freeze window, it'll need to be merged into
the branch being released, which is done by adding a Merge-Requested label.
Once it's been updated to "Merge-Approved" by a TPM, please merge into the
required release branch. You can ask karen@ for merge approve help.
Example: http://crbug.com/221281
Note however that this is only during the transition period.
build-image will be modified to generate the license for each board and save
the file in /opt/google/chrome/resources/about_os_credits.html or as defined
in http://crbug.com/271832 .
"""
from __future__ import print_function
import os
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import osutils
from chromite.licensing import licenses_lib
EXTRA_LICENSES_DIR = os.path.join(licenses_lib.SCRIPT_DIR,
'extra_package_licenses')
# These packages exist as workarounds....
EXTRA_PACKAGES = (
('sys-kernel/Linux-2.6',
['http://www.kernel.org/'], ['GPL-2'], []),
('app-arch/libarchive-3.1.2',
['http://www.libarchive.org/'], ['BSD', 'public-domain'],
['libarchive-3.1.2.LICENSE']),
)
def LoadPackageInfo(board, all_packages, generateMissing, packages):
"""Do the work when we're not called as a hook."""
logging.info("Using board %s.", board)
builddir = os.path.join(cros_build_lib.GetSysroot(board=board),
'tmp', 'portage')
if not os.path.exists(builddir):
raise AssertionError(
"FATAL: %s missing.\n"
"Did you give the right board and build that tree?" % builddir)
detect_packages = not packages
if detect_packages:
# If no packages were specified, we look up the full list.
packages = licenses_lib.ListInstalledPackages(board, all_packages)
if not packages:
raise AssertionError('FATAL: Could not get any packages for board %s' %
board)
logging.debug("Initial Package list to work through:\n%s",
'\n'.join(sorted(packages)))
licensing = licenses_lib.Licensing(board, packages, generateMissing)
licensing.LoadPackageInfo()
logging.debug("Package list to skip:\n%s",
'\n'.join([p for p in sorted(packages)
if licensing.packages[p].skip]))
logging.debug("Package list left to work through:\n%s",
'\n'.join([p for p in sorted(packages)
if not licensing.packages[p].skip]))
licensing.ProcessPackageLicenses()
if detect_packages:
# If we detected 'all' packages, we have to add in these extras.
for fullnamewithrev, homepages, names, files in EXTRA_PACKAGES:
license_texts = [osutils.ReadFile(os.path.join(EXTRA_LICENSES_DIR, f))
for f in files]
licensing.AddExtraPkg(fullnamewithrev, homepages, names, license_texts)
return licensing
def main(args):
parser = commandline.ArgumentParser(usage=__doc__)
parser.add_argument("-b", "--board",
help="which board to run for, like x86-alex")
parser.add_argument("-p", "--package", action="append", default=[],
dest="packages",
help="check the license of the package, e.g.,"
"dev-libs/libatomic_ops-7.2d")
parser.add_argument("-a", "--all-packages", action="store_true",
dest="all_packages",
help="Run licensing against all packages in the "
"build tree, instead of just virtual/target-os "
"dependencies.")
parser.add_argument("-g", "--generate-licenses", action="store_true",
dest="gen_licenses",
help="Generate license information, if missing.")
parser.add_argument("-o", "--output", type="path",
help="which html file to create with output")
opts = parser.parse_args(args)
if not opts.board:
raise AssertionError("No board given (--board)")
if not opts.output and not opts.gen_licenses:
raise AssertionError("You must specify --output and/or --generate-licenses")
if opts.gen_licenses and os.geteuid() != 0:
raise AssertionError("Run with sudo if you use --generate-licenses.")
licensing = LoadPackageInfo(
opts.board, opts.all_packages, opts.gen_licenses, opts.packages)
if opts.output:
licensing.GenerateHTMLLicenseOutput(opts.output)