blob: 723b2db3c7dbe9e8a7d1452a0acb3b670dd5a4f8 [file] [log] [blame]
# 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 module manages interactions between an image and a public key."""
import os
import tempfile
import constants
from chromite.lib import cros_build_lib
from chromite.lib import git
from chromite.lib import osutils
def MountImage(image_path, root_dir, stateful_dir, read_only):
"""Mounts a Chromium OS image onto mount dir points."""
from_dir, image = os.path.split(image_path)
cmd = ['./mount_gpt_image.sh',
'--from=%s' % from_dir,
'--image=%s' % image,
'--rootfs_mountpt=%s' % root_dir,
'--stateful_mountpt=%s' % stateful_dir]
if read_only: cmd.append('--read_only')
cros_build_lib.RunCommandCaptureOutput(
cmd, print_cmd=False, cwd=constants.CROSUTILS_DIR)
def UnmountImage(root_dir, stateful_dir):
"""Unmounts a Chromium OS image specified by mount dir points."""
cmd = ['./mount_gpt_image.sh', '--unmount', '--rootfs_mountpt=%s' % root_dir,
'--stateful_mountpt=%s' % stateful_dir]
cros_build_lib.RunCommandCaptureOutput(
cmd, print_cmd=False, cwd=constants.CROSUTILS_DIR)
class PublicKeyManager(object):
"""Class wrapping interactions with a public key on an image."""
TARGET_KEY_PATH = 'usr/share/update_engine/update-payload-key.pub.pem'
def __init__(self, image_path, key_path):
"""Initializes a manager with image_path and key_path we plan to insert."""
self.image_path = image_path
self.key_path = key_path
self._rootfs_dir = tempfile.mkdtemp(suffix='rootfs', prefix='tmp')
self._stateful_dir = tempfile.mkdtemp(suffix='stateful', prefix='tmp')
# Gather some extra information about the image.
try:
MountImage(image_path, self._rootfs_dir, self._stateful_dir,
read_only=True)
self._full_target_key_path = os.path.join(
self._rootfs_dir, PublicKeyManager.TARGET_KEY_PATH)
self._is_key_new = True
if os.path.exists(self._full_target_key_path):
cmd = ['diff', self.key_path, self._full_target_key_path]
res = cros_build_lib.RunCommandCaptureOutput(
cmd, print_cmd=False, error_code_ok=True)
if not res.output: self._is_key_new = False
finally:
UnmountImage(self._rootfs_dir, self._stateful_dir)
def __del__(self):
"""Remove our temporary directories we created in init."""
os.rmdir(self._rootfs_dir)
os.rmdir(self._stateful_dir)
def AddKeyToImage(self):
"""Adds the key specified in init to the image."""
if not self._is_key_new:
cros_build_lib.Info('Public key already on image %s. No work to do.',
self.image_path)
return
cros_build_lib.Info('Copying %s into %s', self.key_path, self.image_path)
try:
MountImage(self.image_path, self._rootfs_dir, self._stateful_dir,
read_only=False)
dir_path = os.path.dirname(self._full_target_key_path)
osutils.SafeMakedirs(dir_path, sudo=True)
cmd = ['cp', '--force', '-p', self.key_path, self._full_target_key_path]
cros_build_lib.SudoRunCommand(cmd)
finally:
UnmountImage(self._rootfs_dir, self._stateful_dir)
self._MakeImageBootable()
def _MakeImageBootable(self):
"""Makes the image bootable. Note, it is only useful for non-vm images."""
from_dir, image = os.path.split(self.image_path)
if 'qemu' not in image:
from_dir = git.ReinterpretPathForChroot(from_dir)
cmd = ['bin/cros_make_image_bootable', from_dir, image,
'--force_developer_mode']
cros_build_lib.RunCommandCaptureOutput(
cmd, print_cmd=False, enter_chroot=True, cwd=constants.SOURCE_ROOT)