devserver: return correct IsDelta value in Omaha response
The devserver now uses the newly introduced update_payload module to
actually parse payload files and determine whether they are delta/full
with certainty. This fix includes both locally and remotely served
files. Also fixes a potential problem with remote file attribute
fetching.
BUG=chromium-os:37688
TEST=(1) update response contains correct IsDelta value; (2)
api/fileinfo correctly returns is_delta value.
CQ-DEPEND=I8f426f55d2ee7fb0fa265ae4d5ad84f3c68ca702
Change-Id: I7258d81a66a5c763cc62f6800965fe1a57a0008e
Reviewed-on: https://gerrit.chromium.org/gerrit/43537
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
diff --git a/autoupdate.py b/autoupdate.py
index 1f71ef4..31003e8 100644
--- a/autoupdate.py
+++ b/autoupdate.py
@@ -5,16 +5,24 @@
import json
import os
import subprocess
+import sys
import time
import urllib2
import urlparse
import cherrypy
+# Allow importing from dev/host/lib when running from source tree.
+lib_dir = os.path.join(os.path.dirname(__file__), 'host', 'lib')
+if os.path.exists(lib_dir) and os.path.isdir(lib_dir):
+ sys.path.insert(1, lib_dir)
+
from build_util import BuildObject
import autoupdate_lib
import common_util
import log_util
+# pylint: disable=F0401
+import update_payload
# Module-local log function.
@@ -277,16 +285,15 @@
return image_name
@staticmethod
- def _IsDeltaFormatFile(filename):
+ def IsDeltaFormatFile(filename):
try:
- file_handle = open(filename, 'r')
- delta_magic = 'CrAU'
- magic = file_handle.read(len(delta_magic))
- return magic == delta_magic
- except IOError:
- # For unit tests, we may not have real files, so it's ok to
- # ignore these IOErrors. In any case, this value is not being
- # used in update_engine at all as of now.
+ with open(filename) as payload_file:
+ payload = update_payload.Payload(payload_file)
+ payload.Init()
+ return payload.IsDelta()
+ except (IOError, update_payload.PayloadError):
+ # For unit tests we may not have real files, so it's ok to ignore these
+ # errors.
return False
def GenerateUpdateFile(self, src_image, image_path, output_dir):
@@ -432,12 +439,10 @@
# Generation complete, copy if requested.
if self.copy_to_static_root:
# The final results exist directly in static
- update_payload = os.path.join(static_image_dir,
- UPDATE_FILE)
- stateful_payload = os.path.join(static_image_dir,
- STATEFUL_FILE)
+ cros_update_payload = os.path.join(static_image_dir, UPDATE_FILE)
+ stateful_payload = os.path.join(static_image_dir, STATEFUL_FILE)
metadata_file = os.path.join(static_image_dir, METADATA_FILE)
- common_util.CopyFile(cache_update_payload, update_payload)
+ common_util.CopyFile(cache_update_payload, cros_update_payload)
common_util.CopyFile(cache_stateful_payload, stateful_payload)
common_util.CopyFile(cache_metadata_file, metadata_file)
return None
@@ -565,9 +570,6 @@
if not metadata_obj:
raise AutoupdateError('Failed to obtain remote payload info')
- if not metadata_obj.is_delta_format:
- metadata_obj.is_delta_format = ('_mton' in url) or ('_nton' in url)
-
return metadata_obj
except IOError as e:
raise AutoupdateError('Failed to obtain remote payload info: %s', e)
@@ -593,7 +595,7 @@
sha1 = common_util.GetFileSha1(filename)
sha256 = common_util.GetFileSha256(filename)
size = common_util.GetFileSize(filename)
- is_delta_format = self._IsDeltaFormatFile(filename)
+ is_delta_format = self.IsDeltaFormatFile(filename)
metadata_obj = UpdateMetadata(sha1, sha256, size, is_delta_format)
Autoupdate._StoreMetadataToFile(payload_dir, metadata_obj)
diff --git a/devserver.py b/devserver.py
index 6621e53..8378b76 100755
--- a/devserver.py
+++ b/devserver.py
@@ -300,9 +300,16 @@
file_sha256 = common_util.GetFileSha256(file_path)
except os.error, e:
raise DevServerError('failed to get info for file %s: %s' %
- (file_path, str(e)))
- return json.dumps(
- {'size': file_size, 'sha1': file_sha1, 'sha256': file_sha256})
+ (file_path, e))
+
+ is_delta = autoupdate.Autoupdate.IsDeltaFormatFile(file_path)
+
+ return json.dumps({
+ autoupdate.Autoupdate.SIZE_ATTR: file_size,
+ autoupdate.Autoupdate.SHA1_ATTR: file_sha1,
+ autoupdate.Autoupdate.SHA256_ATTR: file_sha256,
+ autoupdate.Autoupdate.ISDELTA_ATTR: is_delta
+ })
class DevServerRoot(object):
diff --git a/host/__init__.py b/host/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/host/__init__.py