Set up a network service bootstrap.
This adds a script to download network service binaries identified by
a versioned stamp kept in services/network/VERSION and adds a DEPS hook
to run it at gclient --sync.
BUG=450356
R=jamesr@chromium.org
Review URL: https://codereview.chromium.org/869193005
diff --git a/.gitignore b/.gitignore
index 41c17be..9a867a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,6 +26,7 @@
/out/
/out_*/
/sdch/open-vcdiff/
+/services/network/prebuilt/
/testing/gmock/
/testing/gtest/
/third_party/android_tools/
diff --git a/DEPS b/DEPS
index 0dd8e35..fc8b36f 100644
--- a/DEPS
+++ b/DEPS
@@ -317,6 +317,13 @@
'-s', 'src/build/linux/bin/eu-strip.sha1',
],
},
+ # Pull the prebuilt network service binaries according to
+ # services/network/VERSION.
+ {
+ 'name': 'download_network_service',
+ 'pattern': '',
+ 'action': [ 'python', 'src/services/network/download_network_service.py' ],
+ },
{
# Ensure that we don't accidentally reference any .pyc files whose
# corresponding .py files have already been deleted.
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn
new file mode 100644
index 0000000..df5578b
--- /dev/null
+++ b/services/network/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+copy("copy_prebuilt_network_service") {
+ filename = "network_service.mojo"
+ if (is_android) {
+ sources = [
+ "prebuilt/android-arm/$filename",
+ ]
+ } else {
+ assert(is_linux)
+ sources = [
+ "prebuilt/linux-x64/$filename",
+ ]
+ }
+ outputs = [
+ "$root_out_dir/$filename",
+ ]
+}
diff --git a/services/network/VERSION b/services/network/VERSION
new file mode 100644
index 0000000..2f3fb49
--- /dev/null
+++ b/services/network/VERSION
@@ -0,0 +1 @@
+749f2049192aedba7a1cb165ad80ab8afdb047e0
diff --git a/services/network/download_network_service.py b/services/network/download_network_service.py
new file mode 100755
index 0000000..1859b90
--- /dev/null
+++ b/services/network/download_network_service.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import os
+import sys
+import tempfile
+import zipfile
+
+_PLATFORMS = ["linux-x64", "android-arm"]
+
+if not sys.platform.startswith("linux"):
+ print "Not supported for your platform"
+ sys.exit(0)
+
+# Add //tools to the system path so that we can import the gs helper.
+script_dir = os.path.dirname(os.path.realpath(__file__))
+tools_path = os.path.join(script_dir, os.pardir, os.pardir, "tools")
+sys.path.insert(0, tools_path)
+# pylint: disable=F0401
+import gs
+
+
+def download_binary(version, platform, prebuilt_directory):
+ gs_path = "gs://mojo/network/%s/%s.zip" % (version, platform)
+ output_directory = os.path.join(prebuilt_directory, platform)
+ binary_name = "network_service.mojo"
+
+ with tempfile.NamedTemporaryFile() as temp_zip_file:
+ gs.download_from_public_bucket(gs_path, temp_zip_file.name)
+ with zipfile.ZipFile(temp_zip_file.name) as z:
+ zi = z.getinfo(binary_name)
+ mode = zi.external_attr >> 16
+ z.extract(zi, output_directory)
+ os.chmod(os.path.join(output_directory, binary_name), mode)
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description="Download prebuilt network service binaries from google " +
+ "storage")
+ parser.parse_args()
+
+ prebuilt_directory_path = os.path.join(script_dir, "prebuilt")
+ stamp_path = os.path.join(prebuilt_directory_path, "STAMP")
+ version_path = os.path.join(script_dir, "VERSION")
+ with open(version_path) as version_file:
+ version = version_file.read().strip()
+
+ try:
+ with open(stamp_path) as stamp_file:
+ current_version = stamp_file.read().strip()
+ if current_version == version:
+ return 0 # Already have the right version.
+ except IOError:
+ pass # If the stamp file does not exist we need to download a new binary.
+
+ for platform in _PLATFORMS:
+ download_binary(version, platform, prebuilt_directory_path)
+
+ with open(stamp_path, 'w') as stamp_file:
+ stamp_file.write(version)
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/tools/gs.py b/tools/gs.py
new file mode 100755
index 0000000..65e6e43
--- /dev/null
+++ b/tools/gs.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+import subprocess
+import find_depot_tools
+
+def download_from_public_bucket(gs_path, output_path):
+ depot_tools_path = find_depot_tools.add_depot_tools_to_path()
+ gsutil_exe = os.path.join(depot_tools_path, "third_party", "gsutil", "gsutil")
+
+ # We're downloading from a public bucket which does not need authentication,
+ # but the user might have busted credential files somewhere such as ~/.boto
+ # that the gsutil script will try (and fail) to use. Setting these
+ # environment variables convinces gsutil not to attempt to use these, but
+ # also generates a useless warning about failing to load the file. We want
+ # to discard this warning but still preserve all output in the case of an
+ # actual failure. So, we run the script and capture all output and then
+ # throw the output away if the script succeeds (return code 0).
+ env = os.environ.copy()
+ env["AWS_CREDENTIAL_FILE"] = ""
+ env["BOTO_CONFIG"] = ""
+ try:
+ subprocess.check_output(
+ [gsutil_exe,
+ "--bypass_prodaccess",
+ "cp",
+ gs_path,
+ output_path],
+ stderr=subprocess.STDOUT,
+ env=env)
+ except subprocess.CalledProcessError as e:
+ print e.output
+ sys.exit(1)