OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 """This module manages interactions between an image and a public key.""" |
| 6 |
| 7 import os |
| 8 import tempfile |
| 9 |
| 10 import cros_build_lib as cros_lib |
| 11 |
| 12 class PublicKeyManager(object): |
| 13 """Class wrapping interactions with a public key on an image.""" |
| 14 TARGET_KEY_PATH = 'usr/share/update_engine/update-payload-key.pub.pem' |
| 15 |
| 16 def __init__(self, image_path, key_path): |
| 17 """Initializes a manager with image_path and key_path we plan to insert.""" |
| 18 self.image_path = image_path |
| 19 self.key_path = key_path |
| 20 self._rootfs_dir = tempfile.mkdtemp(suffix='rootfs', prefix='tmp') |
| 21 self._stateful_dir = tempfile.mkdtemp(suffix='stateful', prefix='tmp') |
| 22 |
| 23 # Gather some extra information about the image. |
| 24 try: |
| 25 cros_lib.MountImage(image_path, self._rootfs_dir, self._stateful_dir, |
| 26 read_only=True) |
| 27 self._full_target_key_path = os.path.join( |
| 28 self._rootfs_dir, PublicKeyManager.TARGET_KEY_PATH) |
| 29 self._is_key_new = True |
| 30 if os.path.exists(self._full_target_key_path): |
| 31 diff_output = cros_lib.RunCommand(['diff', |
| 32 self.key_path, |
| 33 self._full_target_key_path], |
| 34 print_cmd=False, redirect_stdout=True, |
| 35 redirect_stderr=True, error_ok=True) |
| 36 |
| 37 if not diff_output: self._is_key_new = False |
| 38 |
| 39 finally: |
| 40 cros_lib.UnmountImage(self._rootfs_dir, self._stateful_dir) |
| 41 |
| 42 def __del__(self): |
| 43 """Remove our temporary directories we created in init.""" |
| 44 os.rmdir(self._rootfs_dir) |
| 45 os.rmdir(self._stateful_dir) |
| 46 |
| 47 def AddKeyToImage(self): |
| 48 """Adds the key specified in init to the image.""" |
| 49 if not self._is_key_new: |
| 50 cros_lib.Info('Public key already on image %s. No work to do.' % |
| 51 self.image_path) |
| 52 return |
| 53 |
| 54 cros_lib.Info('Copying %s into %s' % (self.key_path, self.image_path)) |
| 55 try: |
| 56 cros_lib.MountImage(self.image_path, self._rootfs_dir, self._stateful_dir, |
| 57 read_only=False) |
| 58 |
| 59 dir_path = os.path.dirname(self._full_target_key_path) |
| 60 cros_lib.RunCommand(['sudo', 'mkdir', '--parents', dir_path], |
| 61 print_cmd=False) |
| 62 cros_lib.RunCommand(['sudo', 'cp', '--force', '-p', self.key_path, |
| 63 self._full_target_key_path], print_cmd=False) |
| 64 finally: |
| 65 cros_lib.UnmountImage(self._rootfs_dir, self._stateful_dir) |
| 66 self._MakeImageBootable() |
| 67 |
| 68 def RemoveKeyFromImage(self): |
| 69 """Removes the key specified in init from the image.""" |
| 70 cros_lib.Info('Removing public key from image %s.' % self.image_path) |
| 71 try: |
| 72 cros_lib.MountImage(self.image_path, self._rootfs_dir, self._stateful_dir, |
| 73 read_only=False) |
| 74 cros_lib.RunCommand(['sudo', 'rm', '--force', self._full_target_key_path], |
| 75 print_cmd=False) |
| 76 finally: |
| 77 cros_lib.UnmountImage(self._rootfs_dir, self._stateful_dir) |
| 78 self._MakeImageBootable() |
| 79 |
| 80 def _MakeImageBootable(self): |
| 81 """Makes the image bootable. Note, it is only useful for non-vm images.""" |
| 82 image = os.path.basename(self.image_path) |
| 83 if 'qemu' in image: |
| 84 return |
| 85 |
| 86 from_dir = os.path.dirname(self.image_path) |
| 87 cros_lib.RunCommand(['bin/cros_make_image_bootable', |
| 88 cros_lib.ReinterpretPathForChroot(from_dir), |
| 89 image], print_cmd=False, redirect_stdout=True, |
| 90 redirect_stderr=True, enter_chroot=True, |
| 91 cwd=cros_lib.CROSUTILS_DIRECTORY) |
OLD | NEW |