summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimanshu Vasishth <hvasishth@google.com>2014-01-21 09:55:30 -0800
committerHimanshu Vasishth <hvasishth@google.com>2014-01-21 09:55:30 -0800
commitef407d861394799632faf4aee60ac319724db048 (patch)
treeb3df0b74b8d79c97ea38d165feff61cd83b51c65
parent495124e2189d8cd811449d68e541a2f4631386b4 (diff)
parent661f29e76945018ac8792100dfd57861dddcd0f4 (diff)
downloadgoogle-compute-image-packages-ef407d861394799632faf4aee60ac319724db048.tar.gz
Merge remote-tracking branch 'upstream/master'
Conflicts: google-daemon/etc/init/google-accounts-manager-task.conf
-rw-r--r--.gitignore4
-rw-r--r--CONTRIB.md64
-rw-r--r--README.md10
-rw-r--r--embed-kernel.sh17
-rw-r--r--gcimagebundle/LICENSE (renamed from image-bundle/LICENSE)0
-rw-r--r--gcimagebundle/MANIFEST.in (renamed from image-bundle/MANIFEST.in)0
-rw-r--r--gcimagebundle/README (renamed from image-bundle/README)0
-rw-r--r--gcimagebundle/README.md (renamed from image-bundle/README.md)0
-rw-r--r--gcimagebundle/VERSION (renamed from image-bundle/VERSION)0
-rw-r--r--gcimagebundle/distribute_setup.py (renamed from image-bundle/distribute_setup.py)0
-rwxr-xr-xgcimagebundle/gcimagebundle (renamed from image-bundle/gcimagebundle)0
-rw-r--r--gcimagebundle/gcimagebundlelib/__init__.py (renamed from image-bundle/gcimagebundlelib/__init__.py)0
-rw-r--r--gcimagebundle/gcimagebundlelib/block_disk.py (renamed from image-bundle/gcimagebundlelib/block_disk.py)28
-rw-r--r--gcimagebundle/gcimagebundlelib/centos.py (renamed from image-bundle/gcimagebundlelib/centos.py)0
-rw-r--r--gcimagebundle/gcimagebundlelib/debian.py (renamed from image-bundle/gcimagebundlelib/debian.py)0
-rw-r--r--gcimagebundle/gcimagebundlelib/exclude_spec.py (renamed from image-bundle/gcimagebundlelib/exclude_spec.py)0
-rw-r--r--gcimagebundle/gcimagebundlelib/fedora.py56
-rw-r--r--gcimagebundle/gcimagebundlelib/fs_copy.py (renamed from image-bundle/gcimagebundlelib/fs_copy.py)0
-rw-r--r--gcimagebundle/gcimagebundlelib/gcel.py (renamed from image-bundle/gcimagebundlelib/gcel.py)0
-rwxr-xr-xgcimagebundle/gcimagebundlelib/imagebundle.py (renamed from image-bundle/gcimagebundlelib/imagebundle.py)35
-rw-r--r--gcimagebundle/gcimagebundlelib/linux.py (renamed from image-bundle/gcimagebundlelib/linux.py)5
-rwxr-xr-xgcimagebundle/gcimagebundlelib/manifest.py (renamed from image-bundle/gcimagebundlelib/manifest.py)0
-rw-r--r--gcimagebundle/gcimagebundlelib/opensuse.py (renamed from image-bundle/gcimagebundlelib/opensuse.py)0
-rw-r--r--gcimagebundle/gcimagebundlelib/os_platform.py (renamed from image-bundle/gcimagebundlelib/os_platform.py)0
-rw-r--r--gcimagebundle/gcimagebundlelib/platform_factory.py (renamed from image-bundle/gcimagebundlelib/platform_factory.py)6
-rw-r--r--gcimagebundle/gcimagebundlelib/rhel.py36
-rw-r--r--gcimagebundle/gcimagebundlelib/sle.py (renamed from image-bundle/gcimagebundlelib/sle.py)3
-rw-r--r--gcimagebundle/gcimagebundlelib/suse.py (renamed from image-bundle/gcimagebundlelib/suse.py)26
-rw-r--r--gcimagebundle/gcimagebundlelib/tests/__init__.py (renamed from image-bundle/gcimagebundlelib/tests/__init__.py)0
-rwxr-xr-xgcimagebundle/gcimagebundlelib/tests/block_disk_test.py (renamed from image-bundle/gcimagebundlelib/tests/block_disk_test.py)4
-rwxr-xr-xgcimagebundle/gcimagebundlelib/tests/image_bundle_test_base.py (renamed from image-bundle/gcimagebundlelib/tests/image_bundle_test_base.py)12
-rwxr-xr-xgcimagebundle/gcimagebundlelib/tests/utils_test.py (renamed from image-bundle/gcimagebundlelib/tests/utils_test.py)5
-rw-r--r--gcimagebundle/gcimagebundlelib/ubuntu.py (renamed from image-bundle/gcimagebundlelib/ubuntu.py)0
-rw-r--r--gcimagebundle/gcimagebundlelib/utils.py (renamed from image-bundle/gcimagebundlelib/utils.py)26
-rwxr-xr-xgcimagebundle/setup.py (renamed from image-bundle/setup.py)2
-rw-r--r--gcimagebundle/stdeb.cfg3
-rwxr-xr-xgoogle-daemon/etc/init.d/google-accounts-manager4
-rwxr-xr-xgoogle-daemon/etc/init.d/google-address-manager2
-rw-r--r--google-daemon/usr/lib/systemd/system/google-accounts-manager.service14
-rw-r--r--google-daemon/usr/lib/systemd/system/google-address-manager.service2
-rw-r--r--google-daemon/usr/share/google/google_daemon/address_manager.py6
-rw-r--r--google-startup-scripts/README.md4
-rwxr-xr-xgoogle-startup-scripts/etc/init.d/google2
-rwxr-xr-xgoogle-startup-scripts/etc/init.d/google-startup-scripts2
-rwxr-xr-xgoogle-startup-scripts/etc/init/google_run_startup_scripts.conf1
-rwxr-xr-xgoogle-startup-scripts/usr/share/google/boto/boot_setup.py7
-rw-r--r--google-startup-scripts/usr/share/google/boto/boto_plugins/compute_auth.py6
-rwxr-xr-xgoogle-startup-scripts/usr/share/google/onboot4
-rwxr-xr-xgoogle-startup-scripts/usr/share/google/virtionet-irq-affinity28
-rw-r--r--image-bundle/.gitignore4
50 files changed, 348 insertions, 80 deletions
diff --git a/.gitignore b/.gitignore
index 66b6e4c..44bff53 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,7 @@
*.pyc
*.pyo
.DS_Store
+.idea
+
+# emacs backup files
+*.*~
diff --git a/CONTRIB.md b/CONTRIB.md
new file mode 100644
index 0000000..caeda73
--- /dev/null
+++ b/CONTRIB.md
@@ -0,0 +1,64 @@
+# How to become a contributor and submit your own code
+
+## Contributor License Agreements
+
+We'd love to accept your sample apps and patches! Before we can take them, we
+have to jump a couple of legal hurdles.
+
+Please fill out either the individual or corporate Contributor License Agreement
+(CLA).
+
+ * If you are an individual writing original source code and you're sure you
+ own the intellectual property, then you'll need to sign an [individual CLA]
+ (https://developers.google.com/open-source/cla/individual).
+ * If you work for a company that wants to allow you to contribute your work,
+ then you'll need to sign a [corporate CLA]
+ (https://developers.google.com/open-source/cla/corporate).
+
+Follow either of the two links above to access the appropriate CLA and
+instructions for how to sign and return it. Once we receive it, we'll be able to
+accept your pull requests.
+
+## Contributing A Patch
+
+1. Submit an issue describing your proposed change to the repo in question.
+1. The repo owner will respond to your issue promptly.
+1. If your proposed change is accepted, and you haven't already done so, sign a
+ Contributor License Agreement (see details above).
+1. Fork the desired repo, develop and test your code changes.
+1. Ensure that your code adheres to the existing style in the sample to which
+ you are contributing. Refer to the
+ [Google Cloud Platform Samples Style Guide]
+ (https://github.com/GoogleCloudPlatform/Template/wiki/style.html) for the
+ recommended coding standards for this organization.
+1. Ensure that your code has an appropriate set of unit tests which all pass.
+1. Submit a pull request.
+
+## Contributing A New Sample App
+
+1. Submit an issue to the GoogleCloudPlatform/Template repo describing your
+ proposed sample app.
+1. The Template repo owner will respond to your enhancement issue promptly.
+ Instructional value is the top priority when evaluating new app proposals for
+ this collection of repos.
+1. If your proposal is accepted, and you haven't already done so, sign a
+ Contributor License Agreement (see details above).
+1. Create your own repo for your app following this naming convention:
+ * {product}-{app-name}-{language}
+ * products: appengine, compute, storage, bigquery, prediction, cloudsql
+ * example: appengine-guestbook-python
+ * For multi-product apps, concatenate the primary products, like this:
+ compute-appengine-demo-suite-python.
+ * For multi-language apps, concatenate the primary languages like this:
+ appengine-sockets-python-java-go.
+
+1. Clone the README.md, CONTRIB.md and LICENSE files from the
+ GoogleCloudPlatform/Template repo.
+1. Ensure that your code adheres to the existing style in the sample to which
+ you are contributing. Refer to the
+ [Google Cloud Platform Samples Style Guide]
+ (https://github.com/GoogleCloudPlatform/Template/wiki/style.html) for the
+ recommended coding standards for this organization.
+1. Ensure that your code has an appropriate set of unit tests which all pass.
+1. Submit a request to fork your repo in GoogleCloudPlatform organizationt via
+ your proposal issue.
diff --git a/README.md b/README.md
index e937bdc..198ca93 100644
--- a/README.md
+++ b/README.md
@@ -13,5 +13,15 @@ Refer to [Building a Google Compute Engine Image](https://developers.google.com/
## Source Code
This repository is structured so that each package is located in its own top-level directory. [`google-startup-scripts`](google-startup-scripts/) and [`google-daemon`](google-daemon/) are stored as the directory structure of where the files would be from root. [`image-bundle`](image-bundle/) has no directory structure.
+## Contributing
+Have a patch that will benefit this project? Awesome! Follow these steps to have it accepted.
+
+1. Please sign our [Contributor License Agreement](CONTRIB.md).
+1. Fork this Git repository and make your changes.
+1. Run the unit tests. (gcimagebundle only)
+1. Create a Pull Request
+1. Incorporate review feedback to your changes.
+1. Accepted!
+
## License
All files in this repository are under the [Apache License, Version 2.0](LICENSE) unless noted otherwise.
diff --git a/embed-kernel.sh b/embed-kernel.sh
index 94d2292..57c09f4 100644
--- a/embed-kernel.sh
+++ b/embed-kernel.sh
@@ -105,11 +105,15 @@ debian_embed_script=/tmp/debian-embed-kernel.bash
cat > $debian_embed_script << EOF
set -x
export PATH=$PATH:/usr/sbin
+echo '### Migrate disk step 5b'
sudo apt-get -y install linux-image-amd64
sudo apt-get -y install debconf-utils
echo 'grub-pc grub-pc/install_devices multiselect /dev/sda' |debconf-set-selections
+echo '### Migrate disk step 5c'
sudo apt-get -y install grub-pc
+echo '### Migrate disk step 5d'
curl -L --remote-name-all https://github.com/GoogleCloudPlatform/compute-image-packages/releases/download/1.1.0.1/google-startup-scripts_1.1.0-4_all.deb https://github.com/GoogleCloudPlatform/compute-image-packages/releases/download/1.1.0.1/google-compute-daemon_1.1.0-4_all.deb https://github.com/GoogleCloudPlatform/compute-image-packages/releases/download/1.1.0.1/python-gcimagebundle_1.1.0-3_all.deb
+echo '### Migrate disk step 5e'
sudo dpkg -i google-startup-scripts_1.1.0-4_all.deb google-compute-daemon_1.1.0-4_all.deb python-gcimagebundle_1.1.0-3_all.deb
sudo apt-get -f -y install
sudo shutdown -h now
@@ -167,6 +171,7 @@ EOF
embed_script=/tmp/embed$RANDOM.bash
cat > $embed_script << 'EOF'
+echo '### Migrate disk step 5a'
set -x
RELEASE_FILE=`ls /etc/*-release`
echo $RELEASE_FILE
@@ -201,6 +206,7 @@ EOF
pushScript $centos_embed_script
pushScript $debian_embed_script
+ echo '### Migrate disk step 4'
# Run the script to embed the kernel
echo 'embeding Kernel'
runRemoteScript 'sudo '$embed_script
@@ -295,10 +301,12 @@ function embedKernelOnDisk() {
temp_instance_zone=$source_disk_zone
if [ -n "$running_instance_name" ]; then
+ echo '### Migrate disk step 2'
temp_instance_name=$running_instance_name
deleteinstance '--nodelete_boot_pd'
fi
+ echo '### Migrate disk step 3'
# Create a snapshot before we update the disk
echo 'Creating snapshot '$source_disk_name-migrate-backup
$gcutil --project=$project_name --service_version=v1 addsnapshot $source_disk_name-migrate-backup --source_disk=$source_disk_name
@@ -310,14 +318,17 @@ function embedKernelOnDisk() {
cleanup_required=true
embedKernel
+ echo '### Migrate disk step 6'
# Delete the temporary instance
echo 'Deleting instance which was created v1beta16'
deleteinstance '--nodelete_boot_pd'
+ echo '### Migrate disk step 7'
# Re-create the instance using the kernel on the disk
echo 'Adding instance with v1'
addInstanceWithV1 $source_disk_name
+ echo '### Migrate disk step 8'
# Verify that the instance is sshable
echo 'Verifying kernel on the instance'
runRemoteScript '/bin/uname -a'
@@ -327,8 +338,9 @@ function embedKernelOnDisk() {
deleteinstance '--nodelete_boot_pd'
fi
+ echo '### Migrate disk step 9'
echo 'A snapshot ('$source_disk_name-migrate-backup') was created as part of running this script. Since you are charged for snapshot storage, you may want to delete this snapshot once you are satisfied that the migration is complete.'
- echo 'Kernel has been embedded in the disk -'$source_disk_name
+ echo 'Kernel has been embedded in the disk: '$source_disk_name
cleanup_required=false
}
@@ -402,6 +414,9 @@ if [ $resource_type == 'Disk' ] && [ -n "$temp_instance_name" ] && [ -n "$runnin
fi
+echo '### Begining disk migration script based on steps from: '
+echo '### https://developers.google.com/compute/docs/transition-v1#customkernelbinaries'
+
# Ensure cleanup gets called on error
trap cleanup ERR EXIT
diff --git a/image-bundle/LICENSE b/gcimagebundle/LICENSE
index 04cb0d7..04cb0d7 100644
--- a/image-bundle/LICENSE
+++ b/gcimagebundle/LICENSE
diff --git a/image-bundle/MANIFEST.in b/gcimagebundle/MANIFEST.in
index 6bbb29c..6bbb29c 100644
--- a/image-bundle/MANIFEST.in
+++ b/gcimagebundle/MANIFEST.in
diff --git a/image-bundle/README b/gcimagebundle/README
index 46f119a..46f119a 100644
--- a/image-bundle/README
+++ b/gcimagebundle/README
diff --git a/image-bundle/README.md b/gcimagebundle/README.md
index ff0f44f..ff0f44f 100644
--- a/image-bundle/README.md
+++ b/gcimagebundle/README.md
diff --git a/image-bundle/VERSION b/gcimagebundle/VERSION
index 9084fa2..9084fa2 100644
--- a/image-bundle/VERSION
+++ b/gcimagebundle/VERSION
diff --git a/image-bundle/distribute_setup.py b/gcimagebundle/distribute_setup.py
index 3553b21..3553b21 100644
--- a/image-bundle/distribute_setup.py
+++ b/gcimagebundle/distribute_setup.py
diff --git a/image-bundle/gcimagebundle b/gcimagebundle/gcimagebundle
index 3ab7ec1..3ab7ec1 100755
--- a/image-bundle/gcimagebundle
+++ b/gcimagebundle/gcimagebundle
diff --git a/image-bundle/gcimagebundlelib/__init__.py b/gcimagebundle/gcimagebundlelib/__init__.py
index e69de29..e69de29 100644
--- a/image-bundle/gcimagebundlelib/__init__.py
+++ b/gcimagebundle/gcimagebundlelib/__init__.py
diff --git a/image-bundle/gcimagebundlelib/block_disk.py b/gcimagebundle/gcimagebundlelib/block_disk.py
index 1453afc..a5e7f9a 100644
--- a/image-bundle/gcimagebundlelib/block_disk.py
+++ b/gcimagebundle/gcimagebundlelib/block_disk.py
@@ -25,7 +25,6 @@ import logging
import os
import re
import tempfile
-import time
from gcimagebundlelib import exclude_spec
from gcimagebundlelib import fs_copy
@@ -43,7 +42,7 @@ class InvalidRawDiskError(Exception):
class FsRawDisk(fs_copy.FsCopy):
"""Creates a raw disk copy of OS image and bundles it into gzipped tar."""
- def __init__(self, fs_size):
+ def __init__(self, fs_size, fs_type):
"""Constructor for FsRawDisk class.
Args:
@@ -51,6 +50,7 @@ class FsRawDisk(fs_copy.FsCopy):
"""
super(FsRawDisk, self).__init__()
self._fs_size = fs_size
+ self._fs_type = fs_type
def _ResizeFile(self, file_path, file_size):
logging.debug('Resizing %s to %s', file_path, file_size)
@@ -125,7 +125,7 @@ class FsRawDisk(fs_copy.FsCopy):
pass
self._excludes.append(exclude_spec.ExcludeSpec(disk_file_path))
- print 'Initializing disk file'
+ logging.info('Initializing disk file')
partition_start = None
uuid = None
if self._disk:
@@ -150,19 +150,17 @@ class FsRawDisk(fs_copy.FsCopy):
# For now we only support disks with a single partition.
if len(devices) != 1:
raise RawDiskError(devices)
- # Sleep for two seconds. At times the loopback device is not ready
- # instantly. Sleeping for two seconds solves it.
- time.sleep(2)
- # List contencts of /dev/mapper to help with debugging. Contents will
+ # List contents of /dev/mapper to help with debugging. Contents will
# be listed in debug log only
utils.RunCommand(['ls', '/dev/mapper'])
- print 'Making filesystem'
- uuid = utils.MakeFileSystem(devices[0], 'ext4', uuid)
+ logging.info('Making filesystem')
+ uuid = utils.MakeFileSystem(devices[0], self._fs_type, uuid)
+ with utils.LoadDiskImage(disk_file_path) as devices:
if uuid is None:
- raise Exception('Could not get uuid from makefilesystem')
+ raise Exception('Could not get uuid from MakeFileSystem')
mount_point = tempfile.mkdtemp(dir=self._scratch_dir)
with utils.MountFileSystem(devices[0], mount_point):
- print 'Copying contents'
+ logging.info('Copying contents')
self._CopySourceFiles(mount_point)
self._CopyPlatformSpecialFiles(mount_point)
self._ProcessOverwriteList(mount_point)
@@ -177,7 +175,7 @@ class FsRawDisk(fs_copy.FsCopy):
tar_entries.append(manifest_file_path)
tar_entries.append(disk_file_path)
- print 'Creating tar.gz archive'
+ logging.info('Creating tar.gz archive')
utils.TarAndGzipFile(tar_entries,
self._output_tarfile)
for tar_entry in tar_entries:
@@ -284,7 +282,7 @@ class FsRawDisk(fs_copy.FsCopy):
"""Update /etc/fstab with the new root fs UUID."""
fstab_path = os.path.join(mount_point, 'etc/fstab')
if not os.path.exists(fstab_path):
- print 'etc/fstab does not exist. Not updating fstab uuid'
+ logging.warning('etc/fstab does not exist. Not updating fstab uuid')
return
f = open(fstab_path, 'r')
@@ -315,8 +313,8 @@ class RootFsRaw(FsRawDisk):
Takes care of additional checks for a root file system.
"""
- def __init__(self, fs_size):
- super(RootFsRaw, self).__init__(fs_size)
+ def __init__(self, fs_size, fs_type):
+ super(RootFsRaw, self).__init__(fs_size, fs_type)
def _Verify(self):
super(RootFsRaw, self)._Verify()
diff --git a/image-bundle/gcimagebundlelib/centos.py b/gcimagebundle/gcimagebundlelib/centos.py
index d54ef9d..d54ef9d 100644
--- a/image-bundle/gcimagebundlelib/centos.py
+++ b/gcimagebundle/gcimagebundlelib/centos.py
diff --git a/image-bundle/gcimagebundlelib/debian.py b/gcimagebundle/gcimagebundlelib/debian.py
index 957e3a7..957e3a7 100644
--- a/image-bundle/gcimagebundlelib/debian.py
+++ b/gcimagebundle/gcimagebundlelib/debian.py
diff --git a/image-bundle/gcimagebundlelib/exclude_spec.py b/gcimagebundle/gcimagebundlelib/exclude_spec.py
index b5bc237..b5bc237 100644
--- a/image-bundle/gcimagebundlelib/exclude_spec.py
+++ b/gcimagebundle/gcimagebundlelib/exclude_spec.py
diff --git a/gcimagebundle/gcimagebundlelib/fedora.py b/gcimagebundle/gcimagebundlelib/fedora.py
new file mode 100644
index 0000000..21d098b
--- /dev/null
+++ b/gcimagebundle/gcimagebundlelib/fedora.py
@@ -0,0 +1,56 @@
+# Copyright 2013 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Fedora specific platform info."""
+
+
+
+import os
+import re
+
+from gcimagebundlelib import linux
+
+
+class Fedora(linux.LinuxPlatform):
+ """Fedora specific information."""
+
+ @staticmethod
+ def IsThisPlatform(root='/'):
+ release_file = root + '/etc/redhat-release'
+ if os.path.exists(release_file):
+ (_, _, flavor, _) = Fedora.ParseRedhatRelease(release_file)
+ if flavor and flavor.lower() == 'fedora':
+ return True
+ return False
+
+ @staticmethod
+ def ParseRedhatRelease(release_file='/etc/redhat-release'):
+ """Parses the /etc/redhat-release file."""
+ f = open(release_file)
+ lines = f.readlines()
+ f.close()
+ if not lines:
+ return (None, None, None, None)
+ line0 = lines[0]
+ g = re.match(r'(\S+) release (\d+) \(([^)]*)\)', line0)
+ if not g:
+ return (None, None, None, None)
+ (osname, version, label) = (g.group(1), g.group(2), g.group(3))
+ return (osname, label, osname, version)
+
+ def __init__(self):
+ super(Fedora, self).__init__()
+ (self.distribution_codename, _, self.distribution,
+ self.distribution_version) = Fedora.ParseRedhatRelease()
diff --git a/image-bundle/gcimagebundlelib/fs_copy.py b/gcimagebundle/gcimagebundlelib/fs_copy.py
index 8989539..8989539 100644
--- a/image-bundle/gcimagebundlelib/fs_copy.py
+++ b/gcimagebundle/gcimagebundlelib/fs_copy.py
diff --git a/image-bundle/gcimagebundlelib/gcel.py b/gcimagebundle/gcimagebundlelib/gcel.py
index 2622cf7..2622cf7 100644
--- a/image-bundle/gcimagebundlelib/gcel.py
+++ b/gcimagebundle/gcimagebundlelib/gcel.py
diff --git a/image-bundle/gcimagebundlelib/imagebundle.py b/gcimagebundle/gcimagebundlelib/imagebundle.py
index d36aa50..b188e3b 100755
--- a/image-bundle/gcimagebundlelib/imagebundle.py
+++ b/gcimagebundle/gcimagebundlelib/imagebundle.py
@@ -37,6 +37,7 @@ def SetupArgsParser():
"""Sets up the command line flags."""
parser = OptionParser()
parser.add_option('-d', '--disk', dest='disk',
+ default='/dev/sda',
help='Disk to bundle.')
parser.add_option('-r', '--root', dest='root_directory',
default='/', metavar='ROOT',
@@ -73,6 +74,9 @@ def SetupArgsParser():
type='int', help='File system size in bytes')
parser.add_option('-b', '--bucket', dest='bucket',
help='Destination storage bucket')
+ parser.add_option('-f', '--filesystem', dest='file_system',
+ default=None,
+ help='File system type for the image.')
return parser
@@ -82,13 +86,13 @@ def VerifyArgs(parser, options):
parser.error('output bundle directory must be specified.')
if not os.path.exists(options.output_directory):
parser.error('output bundle directory does not exist.')
- # TODO(user): add more verification as needed
+ # TODO(user): add more verification as needed
def EnsureSuperUser():
"""Ensures that current user has super user privileges."""
if os.getuid() != 0:
- print 'Tool must be run as root.'
+ logging.warning('Tool must be run as root.')
exit(-1)
@@ -123,23 +127,30 @@ def SetupLogging(options, log_dir='/tmp'):
print 'Starting logging in %s' % logfile
logging.basicConfig(filename=logfile, level=GetLogLevel(options))
console = logging.StreamHandler()
- console.setLevel(logging.INFO)
+ console.setLevel(GetLogLevel(options))
logging.getLogger().addHandler(console)
def PrintVersionInfo():
- #TODO(user): fix up the version string
- print 'version 1.0'
+ #TODO: Should read from the VERSION file instead.
+ logging.info('version 1.1.0')
+
+
+def GetTargetFilesystem(options, guest_platform):
+ if options.file_system:
+ return options.file_system
+ else:
+ return guest_platform.GetPreferredFilesystemType()
def main():
- EnsureSuperUser()
parser = SetupArgsParser()
(options, _) = parser.parse_args()
- VerifyArgs(parser, options)
if options.display_version:
PrintVersionInfo()
return 0
+ EnsureSuperUser()
+ VerifyArgs(parser, options)
scratch_dir = tempfile.mkdtemp(dir=options.output_directory)
SetupLogging(options, scratch_dir)
@@ -147,12 +158,16 @@ def main():
guest_platform = platform_factory.PlatformFactory(
options.root_directory).GetPlatform()
except platform_factory.UnknownPlatformException:
- print 'Could not determine host platform try -s option.'
+ logging.critical('Platform is not supported.'
+ ' Platform rules can be added to platform_factory.py.')
return -1
temp_file_name = tempfile.mktemp(dir=scratch_dir, suffix='.tar.gz')
- bundle = block_disk.RootFsRaw(options.fs_size)
+ file_system = GetTargetFilesystem(options, guest_platform)
+ logging.info('File System: %s', file_system)
+ logging.info('Disk Size: %s bytes', options.fs_size)
+ bundle = block_disk.RootFsRaw(options.fs_size, file_system)
bundle.SetTarfile(temp_file_name)
if options.disk:
readlink_command = ['readlink', '-f', options.disk]
@@ -201,7 +216,7 @@ def main():
options.output_directory, '%s.image.tar.gz' % digest)
os.rename(temp_file_name, output_file)
- print 'Created tar.gz file at %s' % output_file
+ logging.info('Created tar.gz file at %s' % output_file)
if options.bucket:
bucket = options.bucket
diff --git a/image-bundle/gcimagebundlelib/linux.py b/gcimagebundle/gcimagebundlelib/linux.py
index ee40b50..ff8c1d4 100644
--- a/image-bundle/gcimagebundlelib/linux.py
+++ b/gcimagebundle/gcimagebundlelib/linux.py
@@ -20,7 +20,6 @@
import os
import platform
import stat
-import tempfile
from gcimagebundlelib import exclude_spec
from gcimagebundlelib import os_platform
@@ -130,3 +129,7 @@ class LinuxPlatform(os_platform.Platform):
def Overwrite(self, filename, arcname, tmpdir='/tmp'):
"""Overwrites specified file if needed for the Linux platform."""
pass
+
+ def GetPreferredFilesystemType(self):
+ """Return the optimal filesystem supported for the platform."""
+ return 'ext4'
diff --git a/image-bundle/gcimagebundlelib/manifest.py b/gcimagebundle/gcimagebundlelib/manifest.py
index d5ec55e..d5ec55e 100755
--- a/image-bundle/gcimagebundlelib/manifest.py
+++ b/gcimagebundle/gcimagebundlelib/manifest.py
diff --git a/image-bundle/gcimagebundlelib/opensuse.py b/gcimagebundle/gcimagebundlelib/opensuse.py
index 9f709ff..9f709ff 100644
--- a/image-bundle/gcimagebundlelib/opensuse.py
+++ b/gcimagebundle/gcimagebundlelib/opensuse.py
diff --git a/image-bundle/gcimagebundlelib/os_platform.py b/gcimagebundle/gcimagebundlelib/os_platform.py
index 65e6e7c..65e6e7c 100644
--- a/image-bundle/gcimagebundlelib/os_platform.py
+++ b/gcimagebundle/gcimagebundlelib/os_platform.py
diff --git a/image-bundle/gcimagebundlelib/platform_factory.py b/gcimagebundle/gcimagebundlelib/platform_factory.py
index 235705e..da63f0e 100644
--- a/image-bundle/gcimagebundlelib/platform_factory.py
+++ b/gcimagebundle/gcimagebundlelib/platform_factory.py
@@ -18,9 +18,11 @@
import logging
from gcimagebundlelib import centos
+from gcimagebundlelib import fedora
from gcimagebundlelib import debian
from gcimagebundlelib import gcel
from gcimagebundlelib import opensuse
+from gcimagebundlelib import rhel
from gcimagebundlelib import sle
from gcimagebundlelib import ubuntu
@@ -37,12 +39,14 @@ class PlatformFactory(object):
self.__registry = {}
self.__platform_registry = {}
self.Register('Centos', centos.Centos)
+ self.Register('Fedora', fedora.Fedora)
self.Register('Debian', debian.Debian)
self.Register('GCEL', gcel.Gcel)
self.Register('openSUSE', opensuse.OpenSUSE)
+ self.Register('Red Hat Enterprise Linux', rhel.RHEL)
self.Register('SUSE Linux Enterprise', sle.SLE)
self.Register('Ubuntu', ubuntu.Ubuntu)
-
+
def Register(self, name, klass):
self.__registry[name] = klass
diff --git a/gcimagebundle/gcimagebundlelib/rhel.py b/gcimagebundle/gcimagebundlelib/rhel.py
new file mode 100644
index 0000000..3ca63c4
--- /dev/null
+++ b/gcimagebundle/gcimagebundlelib/rhel.py
@@ -0,0 +1,36 @@
+# Copyright 2013 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+"""Red Hat Enterprise Linux Linux specific platform info."""
+
+
+
+import platform
+
+from gcimagebundlelib import linux
+
+
+class RHEL(linux.LinuxPlatform):
+ """Red Hat Enterprise Linux specific information."""
+
+ @staticmethod
+ def IsThisPlatform(root='/'):
+ (distribution, _, _) = platform.linux_distribution()
+ if distribution == 'Red Hat Enterprise Linux Server':
+ return True
+ return False
+
+ def __init__(self):
+ super(RHEL, self).__init__()
diff --git a/image-bundle/gcimagebundlelib/sle.py b/gcimagebundle/gcimagebundlelib/sle.py
index 7fdce3c..8b74827 100644
--- a/image-bundle/gcimagebundlelib/sle.py
+++ b/gcimagebundle/gcimagebundlelib/sle.py
@@ -29,3 +29,6 @@ class SLE(suse.SUSE):
def __init__(self):
super(SLE, self).__init__()
+
+ def GetPreferredFilesystemType(self):
+ return 'ext3'
diff --git a/image-bundle/gcimagebundlelib/suse.py b/gcimagebundle/gcimagebundlelib/suse.py
index 06a2cd5..4911b8b 100644
--- a/image-bundle/gcimagebundlelib/suse.py
+++ b/gcimagebundle/gcimagebundlelib/suse.py
@@ -30,6 +30,8 @@ class SUSE(linux.LinuxPlatform):
self.ParseOSRelease()
if not self.distribution:
self.ParseSUSERelease()
+ if not self.distribution:
+ self.distribution = ''
def ParseOSRelease(self):
"""Parse the /etc/os-release file."""
@@ -60,23 +62,24 @@ class SUSE(linux.LinuxPlatform):
prts = lines[0].split()
cnt = 0
self.distribution = ''
- while 1:
- item = prts[cnt]
- if re.match('\d', item):
- item = None
- break
- elif cnt > 0:
- self.distribution += ' '
- self.distribution += item
- cnt += 1
-
+ if len(prts):
+ while 1:
+ item = prts[cnt]
+ if re.match('\d', item):
+ item = None
+ break
+ elif cnt > 0:
+ self.distribution += ' '
+ self.distribution += item
+ cnt += 1
+
for ln in lines:
if re.match(r'^VERSION =', ln):
self.distribution_version = self.__getData(ln)
if re.match(r'^CODENAME =', ln):
self.distribution_codename = self.__getData(ln)
return
-
+
def __getData(self, ln):
"""Extract data from a line in a file. Either returns data inside the
first double quotes ("a b"; a b in this example) or if no double
@@ -86,4 +89,3 @@ class SUSE(linux.LinuxPlatform):
return ln.split('"')[1]
else:
return ln.split('=')[-1].strip()
-
diff --git a/image-bundle/gcimagebundlelib/tests/__init__.py b/gcimagebundle/gcimagebundlelib/tests/__init__.py
index 42723d7..42723d7 100644
--- a/image-bundle/gcimagebundlelib/tests/__init__.py
+++ b/gcimagebundle/gcimagebundlelib/tests/__init__.py
diff --git a/image-bundle/gcimagebundlelib/tests/block_disk_test.py b/gcimagebundle/gcimagebundlelib/tests/block_disk_test.py
index 66c78c3..75496d8 100755
--- a/image-bundle/gcimagebundlelib/tests/block_disk_test.py
+++ b/gcimagebundle/gcimagebundlelib/tests/block_disk_test.py
@@ -43,7 +43,7 @@ class FsRawDiskTest(image_bundle_test_base.ImageBundleTest):
def setUp(self):
super(FsRawDiskTest, self).setUp()
self._fs_size = 10* FsRawDiskTest._MEGABYTE
- self._bundle = block_disk.FsRawDisk(self._fs_size)
+ self._bundle = block_disk.FsRawDisk(self._fs_size, 'ext4')
self._tar_path = self.tmp_path + '/image.tar.gz'
self._bundle.SetTarfile(self._tar_path)
self._bundle.AppendExcludes([exclude_spec.ExcludeSpec(self._tar_path)])
@@ -421,7 +421,7 @@ class RootFsRawTest(image_bundle_test_base.ImageBundleTest):
def setUp(self):
super(RootFsRawTest, self).setUp()
- self._bundle = block_disk.RootFsRaw(10*1024*1024)
+ self._bundle = block_disk.RootFsRaw(10*1024*1024, 'ext4')
self._tar_path = self.tmp_path + '/image.tar.gz'
self._bundle.SetTarfile(self._tar_path)
self._bundle.AppendExcludes([exclude_spec.ExcludeSpec(self._tar_path)])
diff --git a/image-bundle/gcimagebundlelib/tests/image_bundle_test_base.py b/gcimagebundle/gcimagebundlelib/tests/image_bundle_test_base.py
index 6a990dc..f2f09c9 100755
--- a/image-bundle/gcimagebundlelib/tests/image_bundle_test_base.py
+++ b/gcimagebundle/gcimagebundlelib/tests/image_bundle_test_base.py
@@ -57,15 +57,17 @@ class MockPlatform(Platform):
class MockHttp(utils.Http):
-
+ """Fake implementation of the utils.Http client. Used for metadata queries."""
def __init__(self):
self._instance_response = '{"hostname":"test"}'
- def Get(self, url):
+ def Get(self, request):
+ """Accepts an Http request and returns a precanned response."""
+ url = request.get_full_url()
if url == 'http://metadata/computeMetadata/':
- return 'v1beta1/'
- elif url.startswith('http://metadata/computeMetadata/v1beta1/'):
- url = url.replace('http://metadata/computeMetadata/v1beta1/', '')
+ return 'v1/'
+ elif url.startswith('http://metadata/computeMetadata/v1/'):
+ url = url.replace('http://metadata/computeMetadata/v1/', '')
if url == 'instance/?recursive=true':
return self._instance_response
raise urllib2.HTTPError
diff --git a/image-bundle/gcimagebundlelib/tests/utils_test.py b/gcimagebundle/gcimagebundlelib/tests/utils_test.py
index b64d005..dd7d2cd 100755
--- a/image-bundle/gcimagebundlelib/tests/utils_test.py
+++ b/gcimagebundle/gcimagebundlelib/tests/utils_test.py
@@ -33,9 +33,10 @@ class ImageBundleTest(unittest.TestCase):
def testRunCommandThatFails(self):
"""Run a command that will fail and verify it raises the correct error."""
- non_existent_path = '/' + uuid.uuid4().hex
- with self.assertRaises(subprocess.CalledProcessError):
+ def RunCommandUnderTest():
+ non_existent_path = '/' + uuid.uuid4().hex
utils.RunCommand(['mkfs', '-t', 'ext4', non_existent_path])
+ self.assertRaises(subprocess.CalledProcessError, RunCommandUnderTest)
def main():
diff --git a/image-bundle/gcimagebundlelib/ubuntu.py b/gcimagebundle/gcimagebundlelib/ubuntu.py
index 8d68687..8d68687 100644
--- a/image-bundle/gcimagebundlelib/ubuntu.py
+++ b/gcimagebundle/gcimagebundlelib/ubuntu.py
diff --git a/image-bundle/gcimagebundlelib/utils.py b/gcimagebundle/gcimagebundlelib/utils.py
index ad6a5b0..aa86114 100644
--- a/image-bundle/gcimagebundlelib/utils.py
+++ b/gcimagebundle/gcimagebundlelib/utils.py
@@ -45,7 +45,7 @@ class LoadDiskImage(object):
def __enter__(self):
"""Map disk image as a device."""
- kpartx_cmd = ['kpartx', '-av', self._file_path]
+ kpartx_cmd = ['kpartx', '-a', '-v', '-s', self._file_path]
output = RunCommand(kpartx_cmd)
devs = []
for line in output.splitlines():
@@ -63,7 +63,7 @@ class LoadDiskImage(object):
unused_exc_value: unused.
unused_exc_tb: unused.
"""
- kpartx_cmd = ['kpartx', '-d', self._file_path]
+ kpartx_cmd = ['kpartx', '-d', '-v', '-s', self._file_path]
RunCommand(kpartx_cmd)
@@ -96,8 +96,12 @@ class MountFileSystem(object):
"""
umount_cmd = ['umount', self._dir_path]
RunCommand(umount_cmd)
+ SyncFileSystem()
+def SyncFileSystem():
+ RunCommand(['sync'])
+
def GetMounts(root='/'):
"""Find all mount points under the specified root.
@@ -153,7 +157,7 @@ def MakeFileSystem(dev_path, fs_type, uuid=None):
dev_path: A path to a device.
fs_type: A type of a file system to be created. For example ext2, ext3, etc.
uuid: The value to use as the UUID for the filesystem. If none, a random
- UUID will be generated and used.
+ UUID will be generated and used.
Returns:
The uuid of the filesystem. This will be the same as the passed value if
@@ -380,15 +384,15 @@ def TarAndGzipFile(src_paths, dest):
class Http(object):
- def Get(self, url):
- return urllib2.urlopen(url).read()
+ def Get(self, request):
+ return urllib2.urlopen(request).read()
def GetMetadata(self, url_path, recursive=False):
"""Retrieves instance metadata.
Args:
url_path: The path of the metadata url after the api version.
- http://metadata/computeMetadata/v1beta1/url_path
+ http://metadata/computeMetadata/v1/url_path
recursive: If set, returns the tree of metadata starting at url_path as
a json string.
Returns:
@@ -396,11 +400,11 @@ class Http(object):
"""
# Use the latest version of the metadata.
- base_url = 'http://metadata/computeMetadata/'
- versions = self.Get(base_url).splitlines()
- latest_version = versions[-1]
+ base_url = 'http://metadata/computeMetadata/v1/'
suffix = ''
if recursive:
suffix = '?recursive=true'
- url = '{0}{1}{2}{3}'.format(base_url, latest_version, url_path, suffix)
- return self.Get(url)
+ url = '{0}{1}{2}'.format(base_url, url_path, suffix)
+ request = urllib2.Request(url)
+ request.add_unredirected_header('X-Google-Metadata-Request', 'True')
+ return self.Get(request)
diff --git a/image-bundle/setup.py b/gcimagebundle/setup.py
index c73ec0b..76ccd04 100755
--- a/image-bundle/setup.py
+++ b/gcimagebundle/setup.py
@@ -41,7 +41,7 @@ setup(
long_description=Read('README.md'),
zip_safe=False,
classifiers=[
- 'Development Status :: 4 - Beta',
+ 'Development Status :: 5 - Production/Stable',
'Environment :: Console',
'Intended Audience :: Developers',
'Intended Audience :: System Administrators',
diff --git a/gcimagebundle/stdeb.cfg b/gcimagebundle/stdeb.cfg
new file mode 100644
index 0000000..09364a3
--- /dev/null
+++ b/gcimagebundle/stdeb.cfg
@@ -0,0 +1,3 @@
+[DEFAULT]
+Depends: kpartx, parted, rsync, uuid-runtime
+XS-Python-Version: >= 2.6
diff --git a/google-daemon/etc/init.d/google-accounts-manager b/google-daemon/etc/init.d/google-accounts-manager
index 7bd7fdd..c344252 100755
--- a/google-daemon/etc/init.d/google-accounts-manager
+++ b/google-daemon/etc/init.d/google-accounts-manager
@@ -16,10 +16,10 @@
### BEGIN INIT INFO
# Provides: gce_manage_accounts
# X-Start-Before: ssh
-# Required-Start: $network
+# Required-Start: $local_fs $network $named $syslog
# Required-Stop:
# Default-Start: 2 3 4 5
-# Default-Stop:
+# Default-Stop: 0 1 6
# Short-Description: Google Compute Engine accounts manager service
# Description: This launches the Google Compute Engine accounts manager
# daemon.
diff --git a/google-daemon/etc/init.d/google-address-manager b/google-daemon/etc/init.d/google-address-manager
index f2dac7a..04c027e 100755
--- a/google-daemon/etc/init.d/google-address-manager
+++ b/google-daemon/etc/init.d/google-address-manager
@@ -149,3 +149,5 @@ case "$1" in
exit 3
;;
esac
+
+:
diff --git a/google-daemon/usr/lib/systemd/system/google-accounts-manager.service b/google-daemon/usr/lib/systemd/system/google-accounts-manager.service
new file mode 100644
index 0000000..7808cf2
--- /dev/null
+++ b/google-daemon/usr/lib/systemd/system/google-accounts-manager.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Google Compute Engine User Accounts Manager Daemon
+After=network.target
+Before=sshd.service
+Requires=network.target
+
+[Service]
+ExecStart=/usr/share/google/google_daemon/manage_accounts.py --daemon
+ExecStop=/bin/kill -TERM $MAINPID
+PIDFile=/var/run/google_daemon.pid
+Type=simple
+
+[Install]
+WantedBy=multi-user.target
diff --git a/google-daemon/usr/lib/systemd/system/google-address-manager.service b/google-daemon/usr/lib/systemd/system/google-address-manager.service
index 64adf06..0fc55b1 100644
--- a/google-daemon/usr/lib/systemd/system/google-address-manager.service
+++ b/google-daemon/usr/lib/systemd/system/google-address-manager.service
@@ -1,5 +1,5 @@
[Unit]
-Description=Google Compute Engine Address Manager Deamon
+Description=Google Compute Engine Address Manager Daemon
After=network.target
Requires=network.target
diff --git a/google-daemon/usr/share/google/google_daemon/address_manager.py b/google-daemon/usr/share/google/google_daemon/address_manager.py
index c8d7b70..1b3997c 100644
--- a/google-daemon/usr/share/google/google_daemon/address_manager.py
+++ b/google-daemon/usr/share/google/google_daemon/address_manager.py
@@ -36,7 +36,7 @@ import time
import urllib2
PUBLIC_ENDPOINT_URL_PREFIX = (
-'http://metadata/computeMetadata/v1beta1/instance/network-interfaces/0/forwarded-ips/?recursive=true&alt=text&wait_for_change=true&timeout_sec=60&last_etag=')
+'http://metadata/computeMetadata/v1/instance/network-interfaces/0/forwarded-ips/?recursive=true&alt=text&wait_for_change=true&timeout_sec=60&last_etag=')
GOOGLE_PROTO_ID = 66 # "GG"
class InputError(Exception):
@@ -88,7 +88,9 @@ class AddressManager(object):
# If the connection gets abandoned, ensure we don't hang more than
# 70 seconds.
url = PUBLIC_ENDPOINT_URL_PREFIX + self.last_etag
- u = self.urllib2.urlopen(urllib2.Request(url), timeout=70)
+ request = urllib2.Request(url)
+ request.add_unredirected_header('X-Google-Metadata-Request', 'True')
+ u = self.urllib2.urlopen(request, timeout=70)
addrs_data = u.read()
headers = u.info().dict
self.last_etag = headers.get('etag', self.default_last_etag)
diff --git a/google-startup-scripts/README.md b/google-startup-scripts/README.md
index c772784..76c79eb 100644
--- a/google-startup-scripts/README.md
+++ b/google-startup-scripts/README.md
@@ -1,7 +1,7 @@
## Google Startup Scripts
Google provides a set of startup scripts that interact with the virtual machine environment. On boot, the startup script `/usr/share/google/onboot` queries the instance metadata for a user-provided startup script to run. User-provided startup scripts can be specified in the instance metadata under `startup-script` or, if the metadata is in a small script or a downloadable file, it can be specified `via startup-script-url`. You can use gcutil or the [Google Compute Engine API](https://developers.google.com/compute/docs/reference/latest) to specify a startup script.
-For more information on how to use startup scripts, read the [Using Start Up Scripts documentation](https://devsite.googleplex.com/compute/docs/howtos/startupscript#storescriptremotely).
+For more information on how to use startup scripts, read the [Using Start Up Scripts documentation](https://developers.google.com/compute/docs/howtos/startupscript#storescriptremotely).
Below is an example of metadata that indicates a startup script URL and a startup script file was passed to the instance:
@@ -35,7 +35,7 @@ Google startup scripts also perform the following actions:
Startup scripts check the value of the instance ID at:
- http://metadata/computeMetadata/v1beta1/instance/id
+ http://metadata/computeMetadata/v1/instance/id
and compares it to the last instance ID the disk booted on.
diff --git a/google-startup-scripts/etc/init.d/google b/google-startup-scripts/etc/init.d/google
index 54f04ce..469d282 100755
--- a/google-startup-scripts/etc/init.d/google
+++ b/google-startup-scripts/etc/init.d/google
@@ -71,3 +71,5 @@ case "$1" in
exit 3
;;
esac
+
+:
diff --git a/google-startup-scripts/etc/init.d/google-startup-scripts b/google-startup-scripts/etc/init.d/google-startup-scripts
index b42d4a8..5228a45 100755
--- a/google-startup-scripts/etc/init.d/google-startup-scripts
+++ b/google-startup-scripts/etc/init.d/google-startup-scripts
@@ -69,3 +69,5 @@ case "$1" in
exit 3
;;
esac
+
+:
diff --git a/google-startup-scripts/etc/init/google_run_startup_scripts.conf b/google-startup-scripts/etc/init/google_run_startup_scripts.conf
index ceb6597..c81efd8 100755
--- a/google-startup-scripts/etc/init/google_run_startup_scripts.conf
+++ b/google-startup-scripts/etc/init/google_run_startup_scripts.conf
@@ -8,4 +8,3 @@ script
/usr/share/google/run-startup-scripts
initctl emit --no-wait google-startup-scripts-have-run
end script
-
diff --git a/google-startup-scripts/usr/share/google/boto/boot_setup.py b/google-startup-scripts/usr/share/google/boto/boot_setup.py
index 609c39f..8ff772b 100755
--- a/google-startup-scripts/usr/share/google/boto/boot_setup.py
+++ b/google-startup-scripts/usr/share/google/boto/boot_setup.py
@@ -30,7 +30,7 @@ import textwrap
import urllib2
NUMERIC_PROJECT_ID_URL=('http://metadata.google.internal/'
- 'computeMetadata/v1beta1/project/numeric-project-id')
+ 'computeMetadata/v1/project/numeric-project-id')
SYSTEM_BOTO_CONFIG_TEMPLATE='/etc/boto.cfg.template'
SYSTEM_BOTO_CONFIG='/etc/boto.cfg'
AUTH_PLUGIN_DIR='/usr/share/google/boto/boto_plugins'
@@ -39,8 +39,9 @@ AUTH_PLUGIN_DIR='/usr/share/google/boto/boto_plugins'
def GetNumericProjectId():
"""Get the numeric project ID for this VM."""
try:
- req = urllib2.Request(NUMERIC_PROJECT_ID_URL)
- return urllib2.urlopen(req).read()
+ request = urllib2.Request(NUMERIC_PROJECT_ID_URL)
+ request.add_unredirected_header('X-Google-Metadata-Request', 'True')
+ return urllib2.urlopen(request).read()
except (urllib2.URLError, urllib2.HTTPError, IOError), e:
return None
diff --git a/google-startup-scripts/usr/share/google/boto/boto_plugins/compute_auth.py b/google-startup-scripts/usr/share/google/boto/boto_plugins/compute_auth.py
index 8a449be..989d674 100644
--- a/google-startup-scripts/usr/share/google/boto/boto_plugins/compute_auth.py
+++ b/google-startup-scripts/usr/share/google/boto/boto_plugins/compute_auth.py
@@ -21,7 +21,7 @@ from boto.auth_handler import AuthHandler
from boto.auth_handler import NotReadyToAuthenticate
META_DATA_SERVER_BASE_URL=(
- 'http://metadata.google.internal/computeMetadata/v1beta1')
+ 'http://metadata.google.internal/computeMetadata/v1')
SERVICE_ACCOUNT_SCOPES_URL=(META_DATA_SERVER_BASE_URL +
'/instance/service-accounts/%s/scopes?alt=json')
@@ -57,7 +57,9 @@ class ComputeAuth(AuthHandler):
def __GetJSONMetadataValue(self, url):
try:
- data = urllib2.urlopen(url).read()
+ request = urllib2.Request(url)
+ request.add_unredirected_header('X-Google-Metadata-Request', 'True')
+ data = urllib2.urlopen(request).read()
return json.loads(data)
except (urllib2.URLError, urllib2.HTTPError, IOError), e:
return None
diff --git a/google-startup-scripts/usr/share/google/onboot b/google-startup-scripts/usr/share/google/onboot
index 785526e..29f347b 100755
--- a/google-startup-scripts/usr/share/google/onboot
+++ b/google-startup-scripts/usr/share/google/onboot
@@ -129,8 +129,8 @@ function run_command_with_retry() {
}
function first_boot() {
- if [[ -x /usr/google/share/first-boot ]]; then
- /usr/google/share/first-boot
+ if [[ -x /usr/share/google/first-boot ]]; then
+ /usr/share/google/first-boot
fi
}
diff --git a/google-startup-scripts/usr/share/google/virtionet-irq-affinity b/google-startup-scripts/usr/share/google/virtionet-irq-affinity
index 137717d..c23188f 100755
--- a/google-startup-scripts/usr/share/google/virtionet-irq-affinity
+++ b/google-startup-scripts/usr/share/google/virtionet-irq-affinity
@@ -35,9 +35,37 @@ function log() {
fi
}
+function is_decimal_int() {
+ [ "${1}" -eq "${1}" ] > /dev/null 2>&1
+}
+
+function set_channels() {
+ ethtool -L "${1}" combined "${2}" > /dev/null 2>&1
+}
+
log "Running $(basename $0)"
NET_DEVS=/sys/bus/virtio/drivers/virtio_net/virtio*
+# Loop through all the virtionet devices and enable multi-queue
+if [ -x /sbin/ethtool ]; then
+ for dev in $NET_DEVS; do
+ ETH_DEVS=${dev}/net/*
+ for eth_dev in $ETH_DEVS; do
+ eth_dev=$(basename "$eth_dev")
+ num_max_channels=$(ethtool -l "$eth_dev" | grep -m 1 Combined | cut -f2)
+ [ "${num_max_channels}" -eq "1" ] && continue
+ if is_decimal_int "$num_max_channels" && \
+ set_channels "$eth_dev" "$num_max_channels"; then
+ log "Set channels for $eth_dev to $num_max_channels"
+ else
+ log "Could not set channels for $eth_dev to $num_max_channels"
+ fi
+ done
+ done
+else
+ log "/sbin/ethtool not found: cannot configure virtionet multiqueue"
+fi
+
for dev in $NET_DEVS
do
dev=$(basename "$dev")
diff --git a/image-bundle/.gitignore b/image-bundle/.gitignore
deleted file mode 100644
index 5ebaff2..0000000
--- a/image-bundle/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-# compiled code
-*.pyc
-# emacs backup files
-*.*~