blob: 3d99e8bb3d0b90d86be15f4529d40494e5045955 [file] [log] [blame]
#!/usr/bin/python
# Copyright (c) 2011 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.
"""This script repackages ChromeOS images into a factory bundle.
Usage details in <ChromeOS_root>/src/platform/factory-utils/cros_bundle_readme.
"""
import logging
import os
import shutil
from cb_command_lib import IsInsideChroot, UploadToGsd
from cb_constants import BundlingError, MOUNT_POINT, WORKDIR
from cb_name_lib import RunWithNamingRetries
from cros_bundle_lib import CheckParseOptions, FetchImages, MakeFactoryBundle
from optparse import OptionParser
def CreateParser():
"""Creates a command-line flags parser for testing."""
parser = OptionParser(usage=__doc__)
parser.add_option('-b', '--board', action='store', type='string',
dest='board', help='target board')
parser.add_option('-r', '--release', action='store', type='string',
dest='release', help='release candidate version')
parser.add_option('--factory', action='store', type='string',
dest='factory', help='factory image version')
parser.add_option('-s', '--shim', action='store', type='string',
dest='shim', help='install shim version')
parser.add_option('--recovery', action='store', type='string',
dest='recovery', help='recovery image version')
parser.add_option('--fsi', action='store_true', dest='fsi',
help='use to process for final shipping image')
parser.add_option('--no_firmware', action='store_false', dest='fw',
default=True,
help='use to skip firmware extraction for fsi')
parser.add_option('--version', action='store', type='string', dest='version',
help='release version number for bundle naming, e.g. mp9x')
parser.add_option('--mountpt', action='store', dest='mount_point',
help='specify mount point for SSD image')
parser.add_option('-f', '--force', action='store_true', dest='force',
default=False,
help='force overwrite of any existing bundle files')
parser.add_option('--clean', action='store_true', dest='clean',
default=False,
help='remove all stored bundles files in tmp storage')
parser.add_option('--bundle_dir', action='store', dest='bundle_dir',
help='absolute directory path for factory bundle files' +
', ending is name for factory bundle tar file')
parser.add_option('--tar_dir', action='store', dest='tar_dir',
help='destination directory for factory bundle tar')
parser.add_option('--board2', action='store', type='string', dest='board2',
help='optional second target board')
parser.add_option('--release2', action='store', dest='release2',
help='optional second release image for factory bundle')
parser.add_option('--recovery2', action='store', dest='recovery2',
help='optional second recovery image for factory bundle')
parser.add_option('--log_level', action='store', dest='loglevel',
help='console logging level: DEBUG, INFO, WARNING, ERROR')
parser.add_option('--no_upload', action='store_false', dest='do_upload',
default=True,
help='disables upload to Google Storage for Developers')
parser.add_option('--full_ssd', action='store_true', dest='full_ssd',
default=False,
help='makes full release image with stateful partition')
parser.add_option('--chromeos_root', action='store', dest='chromeos_root',
help='root directory of ChromeOS source tree checkout')
return parser
def HandleParseOptions():
"""Configures and retrieves options from option parser.
Returns:
an object, the options given to the script
the OptionParser used to parse input options
"""
parser = CreateParser()
(options, args) = parser.parse_args()
log_level = dict(DEBUG=logging.DEBUG,
INFO=logging.INFO,
WARNING=logging.WARNING,
ERROR=logging.ERROR)
if options.loglevel:
if options.loglevel not in log_level:
raise BundlingError('Invalid logging level, please see --help and use '
'all caps')
else:
options.loglevel = log_level[options.loglevel]
return (options, parser)
def main():
"""Main method to initiate fetching and processing of bundle components.
Raises:
BundlingError when image fetch or bundle processing fail.
"""
(options, parser) = HandleParseOptions()
if not os.path.exists(WORKDIR):
os.makedirs(WORKDIR)
logging.basicConfig(level=logging.DEBUG,
filename=os.path.join(WORKDIR, 'cros_bundle.log'))
console = logging.StreamHandler()
console.setLevel(options.loglevel if options.loglevel else logging.DEBUG)
logging.getLogger('').addHandler(console)
CheckParseOptions(options, parser)
# TODO(benwin) run basic sanitization checks on options
if IsInsideChroot():
logging.error('Please run this script outside the chroot environment.')
exit()
if options.clean:
logging.info('Cleaning up and exiting.')
if os.path.exists(WORKDIR):
shutil.rmtree(WORKDIR)
exit()
image_names = RunWithNamingRetries(None, FetchImages, options)
if not image_names:
raise BundlingError('Failed to determine URL at which to fetch images, '
'please check the logged URLs attempted.')
if not options.mount_point:
options.mount_point = MOUNT_POINT
tarname = MakeFactoryBundle(image_names, options)
if options.do_upload:
UploadToGsd(tarname)
if __name__ == "__main__":
main()