Index: autoupdate.py |
diff --git a/autoupdate.py b/autoupdate.py |
index b1d5ae779bb70ada4c159d1f7ba400caa55b2063..a8e02fed285101f1682a02396285daf8f9466267 100644 |
--- a/autoupdate.py |
+++ b/autoupdate.py |
@@ -4,13 +4,14 @@ |
from buildutil import BuildObject |
from xml.dom import minidom |
- |
import cherrypy |
import os |
import shutil |
-import socket |
+import subprocess |
+import tempfile |
import time |
+ |
def _LogMessage(message): |
cherrypy.log(message, 'UPDATE') |
@@ -48,6 +49,7 @@ class Autoupdate(BuildObject): |
self.src_image = src_image |
self.vm = vm |
self.board = board |
+ self.crosutils = os.path.join(os.path.dirname(__file__), '../../scripts') |
def _GetSecondsSinceMidnight(self): |
"""Returns the seconds since midnight as a decimal value.""" |
@@ -84,21 +86,6 @@ class Autoupdate(BuildObject): |
return int(latest_tokens[i]) > int(client_tokens[i]) |
return False |
- def _UnpackStatefulPartition(self, image_path, stateful_file): |
- """Given an image, unpacks its stateful partition to stateful_file.""" |
- image_dir = os.path.dirname(image_path) |
- image_file = os.path.basename(image_path) |
- |
- get_offset = '$(cgpt show -b -i 1 %s)' % image_file |
- get_size = '$(cgpt show -s -i 1 %s)' % image_file |
- unpack_command = ( |
- 'cd %s && ' |
- 'dd if=%s of=%s bs=512 skip=%s count=%s' % (image_dir, image_file, |
- stateful_file, get_offset, |
- get_size)) |
- _LogMessage(unpack_command) |
- return os.system(unpack_command) == 0 |
- |
def _UnpackZip(self, image_dir): |
"""Unpacks an image.zip into a given directory.""" |
image = os.path.join(image_dir, self._GetImageName()) |
@@ -248,17 +235,51 @@ class Autoupdate(BuildObject): |
Returns: |
Path to created stateful update_payload or None on error. |
""" |
- stateful_partition_path = '%s/stateful.image' % os.path.dirname(image_path) |
+ _LogMessage('Generating stateful update file.') |
+ from_dir = os.path.dirname(image_path) |
+ image = os.path.basename(image_path) |
+ output_gz = os.path.join(from_dir, 'stateful.tgz') |
- # Unpack to get stateful partition. |
- if self._UnpackStatefulPartition(image_path, stateful_partition_path): |
- mkstatefulupdate_command = 'gzip -f %s' % stateful_partition_path |
- if os.system(mkstatefulupdate_command) == 0: |
- _LogMessage('Successfully generated %s.gz' % stateful_partition_path) |
- return '%s.gz' % stateful_partition_path |
+ # Temporary directories for this function. |
+ rootfs_dir = tempfile.mkdtemp(suffix='rootfs', prefix='tmp') |
+ stateful_dir = tempfile.mkdtemp(suffix='stateful', prefix='tmp') |
- _LogMessage('Failed to create stateful update file') |
- return None |
+ # Mount the image to pull out the important directories. |
+ try: |
+ # Only need stateful partition, but this saves us having to manage our |
+ # own loopback device. |
+ subprocess.check_call(['%s/mount_gpt_image.sh' % self.crosutils, |
+ '--from=%s' % from_dir, |
+ '--image=%s' % image, |
+ '--read_only', |
+ '--rootfs_mountpt=%s' % rootfs_dir, |
+ '--stateful_mountpt=%s' % stateful_dir, |
+ ]) |
+ _LogMessage('Tarring up /usr/local and /var!') |
+ subprocess.check_call(['sudo', |
+ 'tar', |
+ '-czf', |
+ output_gz, |
+ '--directory=%s' % stateful_dir, |
+ 'dev_image', |
+ 'var', |
+ ]) |
+ except: |
+ _LogMessage('Failed to create stateful update file') |
+ raise |
+ finally: |
+ # Unmount best effort regardless. |
+ subprocess.call(['%s/mount_gpt_image.sh' % self.crosutils, |
+ '--unmount', |
+ '--rootfs_mountpt=%s' % rootfs_dir, |
+ '--stateful_mountpt=%s' % stateful_dir, |
+ ]) |
+ # Clean up our directories. |
+ os.rmdir(rootfs_dir) |
+ os.rmdir(stateful_dir) |
+ |
+ _LogMessage('Successfully generated %s' % output_gz) |
+ return output_gz |
def MoveImagesToStaticDir(self, update_path, stateful_update_path, |
static_image_dir): |