def __init__(self, build, work_dir=None, unique=None, ctx=None): """This initializer identifies the build an payload that need signatures. Args: build: An instance of gspaths.Build that defines the build. work_dir: A directory inside the chroot to be used for temporarily manipulating files. The directory should be cleaned by the caller. If it is not passed, a temporary directory will be created. unique: Force known 'unique' id. Mostly for unittests. ctx: GS Context to use for GS operations. """ self._build = build self._ctx = ctx if ctx is not None else gs.GSContext() self._work_dir = work_dir or chroot_util.TempDirInChroot() build_signing_uri = gspaths.ChromeosReleases.BuildPayloadsSigningUri( self._build) # Uniquify the directory using our pid/thread-id. This can't collide # with other hosts because the build is locked to our host in # paygen_build. if unique is None: unique = '%d-%d' % (os.getpid(), threading.current_thread().ident) # This is a partial URI that is extended for a lot of other URIs we use. self.signing_base_dir = os.path.join(build_signing_uri, unique) self.archive_uri = os.path.join(self.signing_base_dir, 'payload.hash.tar.bz2')
def setUp(self): # UnofficialSignerPayloadsClient need a temporary directory inside chroot so # cros_test_lib.TempDirTestCase will not work if we run this unittest # outside the chroot. with chroot_util.TempDirInChroot(delete=False) as dir_in_chroot: self._temp_dir = dir_in_chroot self._client = signer_payloads_client.UnofficialSignerPayloadsClient( private_key=remote_access.TEST_PRIVATE_KEY, work_dir=self._temp_dir)
def testTempDirInChroot(self): """Tests the correctness of TempDirInChroot.""" rm_check_dir = '' with chroot_util.TempDirInChroot() as tempdir: rm_check_dir = tempdir self.assertExists(tempdir) chroot_tempdir = path_util.FromChrootPath('/tmp') self.assertNotEqual(chroot_tempdir, tempdir) self.assertStartsWith(tempdir, chroot_tempdir) self.assertNotExists(rm_check_dir)
def testTempDirInChrootWithBaseDir(self): """Tests the correctness of TempDirInChroot with a passed prefix.""" rm_check_dir = '' chroot_tempdir = path_util.FromChrootPath('/tmp/some-prefix') osutils.SafeMakedirs(chroot_tempdir) with chroot_util.TempDirInChroot(base_dir='/tmp/some-prefix') as tempdir: rm_check_dir = tempdir self.assertExists(tempdir) self.assertNotEqual(chroot_tempdir, tempdir) self.assertStartsWith(tempdir, chroot_tempdir) self.assertNotExists(rm_check_dir) osutils.RmDir(chroot_tempdir)
def CreateAndUploadPayload(payload, sign=True, verify=True): """Helper to create a PaygenPayloadLib instance and use it. Mainly can be used as a single function to help with parallelism. Args: payload: An instance of gspaths.Payload describing the payload to generate. sign: Boolean saying if the payload should be signed (normally, you do). verify: whether the payload should be verified (default: True) """ # We need to create a temp directory inside the chroot so be able to access # from both inside and outside the chroot. with chroot_util.TempDirInChroot() as work_dir: PaygenPayload(payload, work_dir, sign=sign, verify=verify).Run()
def _CreateVMImage(src_dir, dest_dir): """Creates a VM image from a given chromiumos image. Args: src_dir: Path to the directory containing (non-VM) image. Defaults to None to use the latest image for the board. dest_dir: Path to the directory where the VM image should be written. Returns: The path of the created VM image. """ # image_to_vm.sh only runs in chroot, but src_dir / dest_dir may not be # reachable from chroot. Also, image_to_vm.sh needs all the contents of # src_dir to work correctly (it silently does the wrong thing if some files # are missing). # So, create a tempdir reachable from chroot, copy everything to that path, # create vm image there and finally move it all to dest_dir. with chroot_util.TempDirInChroot() as tempdir: logging.debug('Copying images from %s to %s.', src_dir, tempdir) osutils.CopyDirContents(src_dir, tempdir) # image_to_vm.sh doesn't let us provide arbitrary names for the input image. # Instead, it picks the name based on whether we pass in --test_image or not # (and doesn't use that flag for anything else). cmd = [ path_util.ToChrootPath( os.path.join(constants.CROSUTILS_DIR, 'image_to_vm.sh')), '--from=%s' % path_util.ToChrootPath(tempdir), '--disk_layout=16gb-rootfs', '--test_image', ] try: cros_build_lib.run(cmd, enter_chroot=True, cwd=constants.SOURCE_ROOT) except cros_build_lib.RunCommandError as e: raise SetupError('Failed to create VM image for %s: %s' % (src_dir, e)) # Preserve most content, although we should need only the generated VM # image. Other files like boot.desc might be needed elsewhere, but the # source images should no longer be needed. osutils.SafeUnlink(os.path.join(tempdir, constants.BASE_IMAGE_BIN), sudo=True) osutils.SafeUnlink(os.path.join(tempdir, constants.TEST_IMAGE_BIN), sudo=True) osutils.CopyDirContents(tempdir, dest_dir) # The exact name of the output image is hard-coded in image_to_vm.sh return os.path.join(dest_dir, constants.VM_IMAGE_BIN)
def GenerateUpdatePayloadPropertiesFile(payload, output=None): """Generates the update payload's properties file. Args: payload: The path to the input payload. output: The path to the output properties json file. If None, the file will be placed by appending '.json' to the payload file itself. """ if not output: output = payload + '.json' with chroot_util.TempDirInChroot() as work_dir: paygen = PaygenPayload(None, work_dir) properties_map = paygen.GetPayloadPropertiesMap(payload) properties_json = json.dumps(properties_map, sort_keys=True) osutils.WriteFile(output, properties_json)
def GeneratePayload(self): """Do payload generation (& maybe sign) on Google Storage cros images. Returns: True if successful, raises otherwise. """ should_sign = True if self.keyset != '' else False with chroot_util.TempDirInChroot() as temp_dir: self.paygen = paygen_payload_lib.PaygenPayload(self.payload, temp_dir, sign=should_sign, verify=self.verify) self.paygen.Run() return True
def GenerateUpdatePayload(tgt_image, payload, src_image=None, work_dir=None, private_key=None, check=None, out_metadata_hash_file=None): """Generates output payload and verifies its integrity if needed. Args: tgt_image: The path (or uri) to the image. payload: The path (or uri) to the output payload src_image: The path (or uri) to the source image. If passed, a delta payload is generated. work_dir: A working directory inside the chroot. The None, caller has the responsibility to cleanup this directory after this function returns. private_key: The private key to sign the payload. check: If True, it will check the integrity of the generated payload. out_metadata_hash_file: The output metadata hash file. """ tgt_image = gspaths.Image(uri=tgt_image) src_image = gspaths.Image(uri=src_image) if src_image else None payload = gspaths.Payload(tgt_image=tgt_image, src_image=src_image, uri=payload) with chroot_util.TempDirInChroot() as temp_dir: work_dir = work_dir if work_dir is not None else temp_dir paygen = PaygenPayload(payload, work_dir, sign=private_key is not None, verify=check, private_key=private_key) paygen.Run() # TODO(ahassani): These are basically a hack because devserver is still need # the metadata hash file to sign it. But signing logic has been moved to # paygen and in the future this is not needed anymore. if out_metadata_hash_file: shutil.copy(paygen.metadata_hash_file, out_metadata_hash_file)