summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach Marano <zmarano@google.com>2019-05-21 13:40:07 -0700
committerZach Marano <zmarano@google.com>2019-05-21 13:40:07 -0700
commitd2d59253ad3bd219b2834fa6c2fa5b4d2cce4ecc (patch)
tree68d46cee8db77e9b42bd2ac7ffcd24df79e575c2
parent53ea8cd069fb4d9a1984d1c167e54c133033f8da (diff)
parent35ecbe603cc6a4d92410ee80c9f5cc4d13143d67 (diff)
downloadgoogle-compute-image-packages-d2d59253ad3bd219b2834fa6c2fa5b4d2cce4ecc.tar.gz
Merge branch 'development'20190521
-rw-r--r--README.md9
-rw-r--r--daisy_workflows/build_el.wf.json28
-rw-r--r--packages/gce-disk-expand/packaging/gce-disk-expand.spec4
-rwxr-xr-xpackages/gce-disk-expand/packaging/setup_deb.sh2
-rwxr-xr-xpackages/gce-disk-expand/packaging/setup_rpm.sh2
-rwxr-xr-xpackages/gce-disk-expand/src/expandfs-lib.sh4
-rwxr-xr-xpackages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh10
-rwxr-xr-xpackages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs_dummy.sh3
-rwxr-xr-xpackages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install4
-rwxr-xr-xpackages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/xfs_growfs.sh9
-rw-r--r--packages/google-compute-engine-oslogin/packaging/google-compute-engine-oslogin.spec26
-rwxr-xr-xpackages/google-compute-engine-oslogin/packaging/setup_rpm.sh11
-rw-r--r--packages/google-compute-engine/packaging/debian/changelog6
-rw-r--r--packages/google-compute-engine/packaging/google-compute-engine.spec11
-rwxr-xr-xpackages/google-compute-engine/packaging/setup_deb.sh2
-rwxr-xr-xpackages/google-compute-engine/packaging/setup_rpm.sh6
-rw-r--r--packages/google-compute-engine/src/lib/systemd/system/google-accounts-daemon.service1
-rwxr-xr-xpackages/google-compute-engine/src/usr/bin/google_set_multiqueue14
-rw-r--r--packages/python-google-compute-engine/README.md4
-rw-r--r--packages/python-google-compute-engine/google_compute_engine/boto/tests/compute_auth_test.py7
-rw-r--r--packages/python-google-compute-engine/google_compute_engine/compat.py2
-rw-r--r--packages/python-google-compute-engine/google_compute_engine/constants.py6
-rw-r--r--packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_config.py2
-rwxr-xr-xpackages/python-google-compute-engine/google_compute_engine/instance_setup/instance_setup.py41
-rw-r--r--packages/python-google-compute-engine/google_compute_engine/instance_setup/tests/instance_setup_test.py72
-rw-r--r--packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_retriever.py49
-rw-r--r--packages/python-google-compute-engine/google_compute_engine/metadata_scripts/tests/script_retriever_test.py72
-rw-r--r--packages/python-google-compute-engine/packaging/debian/changelog9
-rw-r--r--packages/python-google-compute-engine/packaging/python3-google-compute-engine.spec47
-rwxr-xr-xpackages/python-google-compute-engine/packaging/setup_deb.sh2
-rwxr-xr-xpackages/python-google-compute-engine/packaging/setup_rpm.sh15
-rwxr-xr-xpackages/python-google-compute-engine/setup.py8
32 files changed, 402 insertions, 86 deletions
diff --git a/README.md b/README.md
index f7b698b..ed306f3 100644
--- a/README.md
+++ b/README.md
@@ -43,10 +43,11 @@ CentOS 6 | rpm | 2.6 | upstart
CentOS 7 | rpm | 2.7 | systemd
RHEL 6 | rpm | 2.6 | upstart
RHEL 7 | rpm | 2.7 | systemd
+RHEL 8 | rpm | 3.6 | systemd
Ubuntu 14.04 | deb | 2.7 | upstart
Ubuntu 16.04 | deb | 3.5 or 2.7 | systemd
Ubuntu 18.04 | deb | 3.6 | systemd
-Ubuntu 18.10 | deb | 3.6 | systemd
+Ubuntu 19.04 | deb | 3.7 | systemd
Debian 9 | deb | 3.5 or 2.7 | systemd
We build the following packages for the Linux guest environment.
@@ -123,9 +124,9 @@ EL6 or EL7. Change `DIST` to either 6 or 7 respectively:
```
DIST=7
tee /etc/yum.repos.d/google-cloud.repo << EOM
-[google-cloud-compute]
-name=Google Cloud Compute
-baseurl=https://packages.cloud.google.com/yum/repos/google-cloud-compute-el${DIST}-x86_64
+[google-compute-engine]
+name=Google Compute Engine
+baseurl=https://packages.cloud.google.com/yum/repos/google-compute-engine-el${DIST}-x86_64-stable
enabled=1
gpgcheck=1
repo_gpgcheck=1
diff --git a/daisy_workflows/build_el.wf.json b/daisy_workflows/build_el.wf.json
index 1f577f9..13303fd 100644
--- a/daisy_workflows/build_el.wf.json
+++ b/daisy_workflows/build_el.wf.json
@@ -21,6 +21,12 @@
"setup-disk": {
"CreateDisks": [
{
+ "Name": "disk-el8-build",
+ "SourceImage": "projects/rhel-cloud/global/images/family/rhel-8",
+ "SizeGb": "10",
+ "Type": "pd-ssd"
+ },
+ {
"Name": "disk-el7-build",
"SourceImage": "projects/centos-cloud/global/images/family/centos-7",
"SizeGb": "10",
@@ -37,6 +43,20 @@
"package-build": {
"CreateInstances": [
{
+ "Name": "inst-el8-build",
+ "Disks": [
+ {"Source": "disk-el8-build"}
+ ],
+ "MachineType": "n1-standard-2",
+ "Metadata": {
+ "github_branch": "${github_branch}",
+ "github_repo": "${github_repo}",
+ "output_path": "${output_path}"
+ },
+ "Scopes": ["https://www.googleapis.com/auth/devstorage.read_write"],
+ "StartupScript": "build_el_packages.sh"
+ },
+ {
"Name": "inst-el7-build",
"Disks": [
{"Source": "disk-el7-build"}
@@ -69,6 +89,14 @@
"wait-for-build": {
"WaitForInstancesSignal": [
{
+ "Name": "inst-el8-build",
+ "SerialOutput": {
+ "Port": 1,
+ "SuccessMatch": "BuildSuccess:",
+ "FailureMatch": "BuildFailed:"
+ }
+ },
+ {
"Name": "inst-el7-build",
"SerialOutput": {
"Port": 1,
diff --git a/packages/gce-disk-expand/packaging/gce-disk-expand.spec b/packages/gce-disk-expand/packaging/gce-disk-expand.spec
index d34b08d..a1fb6dd 100644
--- a/packages/gce-disk-expand/packaging/gce-disk-expand.spec
+++ b/packages/gce-disk-expand/packaging/gce-disk-expand.spec
@@ -33,13 +33,13 @@ This package resizes the root partition on first boot using parted.
%install
mv src/expandfs-lib.sh src/usr/share/dracut/modules.d/50expand_rootfs/
-%if 0%{?rhel} == 7
+%if 0%{?rhel} >= 7
./dracut6_7.sh
%endif
rsync -Pravz src/ %{buildroot}
%files
-%if 0%{?rhel} == 7
+%if 0%{?rhel} >= 7
%attr(755,root,root) /usr/lib/dracut/modules.d/50expand_rootfs/*
%else
%attr(755,root,root) /usr/share/dracut/modules.d/50expand_rootfs/*
diff --git a/packages/gce-disk-expand/packaging/setup_deb.sh b/packages/gce-disk-expand/packaging/setup_deb.sh
index 8880efe..ca5be92 100755
--- a/packages/gce-disk-expand/packaging/setup_deb.sh
+++ b/packages/gce-disk-expand/packaging/setup_deb.sh
@@ -26,7 +26,7 @@ fi
sudo apt-get -y install dh-systemd
# DEB creation tools.
-sudo apt-get -y install debhelper devscripts build-essential
+sudo apt-get -y install debhelper devscripts build-essential rsync
rm -rf /tmp/debpackage
mkdir /tmp/debpackage
diff --git a/packages/gce-disk-expand/packaging/setup_rpm.sh b/packages/gce-disk-expand/packaging/setup_rpm.sh
index 52f6a36..106aa6f 100755
--- a/packages/gce-disk-expand/packaging/setup_rpm.sh
+++ b/packages/gce-disk-expand/packaging/setup_rpm.sh
@@ -24,7 +24,7 @@ if [[ $(basename "$working_dir") != $NAME ]]; then
fi
# RPM creation tools.
-sudo yum -y install rpmdevtools
+sudo yum -y install rpmdevtools rsync
rm -rf ${rpm_working_dir}
mkdir -p ${rpm_working_dir}/{SOURCES,SPECS}
diff --git a/packages/gce-disk-expand/src/expandfs-lib.sh b/packages/gce-disk-expand/src/expandfs-lib.sh
index 5126602..92e9ed5 100755
--- a/packages/gce-disk-expand/src/expandfs-lib.sh
+++ b/packages/gce-disk-expand/src/expandfs-lib.sh
@@ -24,7 +24,7 @@ resize_filesystem() {
case "${fs_type}" in
xfs)
echo "XFS filesystems must be mounted to be resized, deferring."
- expand_xfs="true"
+ echo "true" > /tmp/xfs_resize
return 1
;;
ext*)
@@ -136,6 +136,7 @@ parted_resizepart() {
echo "Unable to resize ${disk}${partnum}: ${out}"
return 1
fi
+ udevadm settle
}
# Resizes partition by deleting and recreating with end position.
@@ -184,4 +185,5 @@ parted_resize_mkpart() (
return 1
fi
done
+ udevadm settle
)
diff --git a/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh
index 055f083..cc831b3 100755
--- a/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh
+++ b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh
@@ -13,8 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-expand_xfs="" # Global to message next script.
-
# Contains dracut-specific logic for detecting disk, then calls appropriate
# library functions.
main() {
@@ -26,11 +24,7 @@ main() {
return
fi
- # Wait for any of the initial udev events to finish otherwise growpart
- # might fail.
- udevsettle
-
- if ! out=$(get_partition "$rootdev"); then
+ if ! out=$(split_partition "$rootdev"); then
echo "Failed to detect disk and partition info: ${out}"
return
fi
@@ -63,8 +57,6 @@ main() {
fi
fi
- udevsettle
-
if ! out=$(resize_filesystem "$rootdev"); then
echo "Failed to resize filesystem: ${out}"
return
diff --git a/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs_dummy.sh b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs_dummy.sh
new file mode 100755
index 0000000..c037109
--- /dev/null
+++ b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs_dummy.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# Dummy script, to make sure systemd executes the cmdline stage (which exports
+# the 'root' variable required for expand_root)
diff --git a/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install
index 4b68069..cdd021d 100755
--- a/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install
+++ b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install
@@ -16,8 +16,9 @@
# Dracut install script for RHEL/CentOS
inst "$moddir/expandfs-lib.sh" "/lib/expandfs-lib.sh"
+inst_hook cmdline 50 "$moddir/expand_rootfs_dummy.sh"
inst_hook pre-mount 50 "$moddir/expand_rootfs.sh"
-inst_hook pre-pivot 50 "$moddir/xfs_growfs.sh"
+inst_hook pre-pivot 99 "$moddir/xfs_growfs.sh"
dracut_install parted
dracut_install cut
@@ -25,4 +26,5 @@ dracut_install sed
dracut_install grep
dracut_install resize2fs
dracut_install e2fsck
+dracut_install udevadm
dracut_install -o xfs_growfs
diff --git a/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/xfs_growfs.sh b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/xfs_growfs.sh
index af8d05d..0e77185 100755
--- a/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/xfs_growfs.sh
+++ b/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/xfs_growfs.sh
@@ -14,7 +14,7 @@
# limitations under the License.
main() {
- if [ -z "$expand_xfs" ]; then
+ if [ ! -e /tmp/xfs_resize ]; then
return
fi
@@ -23,11 +23,18 @@ main() {
return
fi
if xfs_growfs -d -n /sysroot; then
+ echo "Mounting filesystem rw."
+ if ! $(mount -o rw,remount /sysroot); then
+ echo "Remount failed."
+ return
+ fi
echo "Resizing XFS filesystem"
if ! out=$(xfs_growfs -d /sysroot); then
echo "Failed to resize: ${out}"
+ mount -o ro,remount /sysroot
return
fi
+ mount -o ro,remount /sysroot
fi
}
diff --git a/packages/google-compute-engine-oslogin/packaging/google-compute-engine-oslogin.spec b/packages/google-compute-engine-oslogin/packaging/google-compute-engine-oslogin.spec
index 7e0799d..b8b0e67 100644
--- a/packages/google-compute-engine-oslogin/packaging/google-compute-engine-oslogin.spec
+++ b/packages/google-compute-engine-oslogin/packaging/google-compute-engine-oslogin.spec
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Force the dist to be el7 to avoid el7.centos.
+# For EL7, if building on CentOS, override dist to be el7.
%if 0%{?rhel} == 7
%define dist .el7
%endif
@@ -29,11 +29,17 @@ BuildRequires: boost-devel
BuildRequires: gcc-c++
BuildRequires: make
BuildRequires: libcurl
-BuildRequires: json-c
+BuildRequires: json-c-devel
BuildRequires: pam-devel
+%if 0%{?rhel} == 8
+BuildRequires: python3-policycoreutils
+Requires: python3-policycoreutils
+%else
BuildRequires: policycoreutils-python
-Requires: boost-regex
Requires: policycoreutils-python
+%endif
+Requires: boost-regex
+Requires: json-c
%define pam_install_path /%{_lib}/security
@@ -41,6 +47,8 @@ Requires: policycoreutils-python
This package contains several libraries and changes to enable OS Login functionality
for Google Compute Engine.
+%global debug_package %{nil}
+
%prep
%setup
@@ -53,10 +61,14 @@ make install DESTDIR=%{buildroot} NSS_INSTALL_PATH=/%{_lib} PAM_INSTALL_PATH=%{p
%files
%doc
-/%{_lib}/libnss_%{name}-%{version}.so
-/%{_lib}/libnss_cache_%{name}-%{version}.so
-%{pam_install_path}/pam_oslogin_admin.so
-%{pam_install_path}/pam_oslogin_login.so
+%attr(0755,-,-) /%{_lib}/libnss_%{name}-%{version}.so
+%attr(0755,-,-) /%{_lib}/libnss_cache_%{name}-%{version}.so
+%if 0%{?rhel} == 8
+/%{_lib}/libnss_oslogin.so.2
+/%{_lib}/libnss_cache_oslogin.so.2
+%endif
+%attr(0755,-,-) %{pam_install_path}/pam_oslogin_admin.so
+%attr(0755,-,-) %{pam_install_path}/pam_oslogin_login.so
/usr/bin/google_authorized_keys
/usr/bin/google_oslogin_control
/usr/bin/google_oslogin_nss_cache
diff --git a/packages/google-compute-engine-oslogin/packaging/setup_rpm.sh b/packages/google-compute-engine-oslogin/packaging/setup_rpm.sh
index f174efe..519247d 100755
--- a/packages/google-compute-engine-oslogin/packaging/setup_rpm.sh
+++ b/packages/google-compute-engine-oslogin/packaging/setup_rpm.sh
@@ -24,11 +24,14 @@ if [[ $(basename "$working_dir") != $NAME ]]; then
exit 1
fi
-# Build dependencies.
-sudo yum -y install make gcc-c++ libcurl-devel json-c json-c-devel pam-devel policycoreutils-python boost-devel
+sudo yum -y install rpmdevtools make gcc-c++ json-c \
+ libcurl-devel pam-devel boost-devel json-c-devel
-# RPM creation tools.
-sudo yum -y install rpmdevtools
+if grep -q '^\(CentOS\|Red Hat\)[^0-9]*8\..' /etc/redhat-release; then
+ sudo yum -y install python3-policycoreutils
+else
+ sudo yum -y install policycoreutils-python
+fi
rm -rf /tmp/rpmpackage
mkdir -p ${rpm_working_dir}/{SOURCES,SPECS}
diff --git a/packages/google-compute-engine/packaging/debian/changelog b/packages/google-compute-engine/packaging/debian/changelog
index a9e9396..862f51e 100644
--- a/packages/google-compute-engine/packaging/debian/changelog
+++ b/packages/google-compute-engine/packaging/debian/changelog
@@ -1,3 +1,9 @@
+google-compute-engine (2.8.15-1) stable; urgency=low
+
+ * Fix XPS settings with more than 64 vCPUs.
+
+ -- Google Cloud Team <gc-team@google.com> Tue, 21 May 2019 12:00:00 -0700
+
google-compute-engine (2.8.14-1) stable; urgency=low
* Upstart systems: only run startup scripts at boot.
diff --git a/packages/google-compute-engine/packaging/google-compute-engine.spec b/packages/google-compute-engine/packaging/google-compute-engine.spec
index 39307cb..aba148d 100644
--- a/packages/google-compute-engine/packaging/google-compute-engine.spec
+++ b/packages/google-compute-engine/packaging/google-compute-engine.spec
@@ -12,16 +12,25 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# For EL7, if building on CentOS, override dist to be el7.
+%if 0%{?rhel} == 7
+ %define dist .el7
+%endif
+
Name: google-compute-engine
Version: %{_version}
-Release: 1.el7
+Release: 1%{?dist}
Summary: Google Compute Engine guest environment.
License: ASL 2.0
Url: https://github.com/GoogleCloudPlatform/compute-image-packages
Source0: %{name}_%{version}.orig.tar.gz
Requires: curl
Requires: google-compute-engine-oslogin
+%if 0%{?rhel} == 8
+Requires: python3-google-compute-engine = %{version}
+%else
Requires: python-google-compute-engine = %{version}
+%endif
Requires: rsyslog
BuildArch: noarch
diff --git a/packages/google-compute-engine/packaging/setup_deb.sh b/packages/google-compute-engine/packaging/setup_deb.sh
index 76cce07..7ad1b02 100755
--- a/packages/google-compute-engine/packaging/setup_deb.sh
+++ b/packages/google-compute-engine/packaging/setup_deb.sh
@@ -14,7 +14,7 @@
# limitations under the License.
NAME="google-compute-engine"
-VERSION="2.8.14"
+VERSION="2.8.15"
working_dir=${PWD}
if [[ $(basename "$working_dir") != $NAME ]]; then
diff --git a/packages/google-compute-engine/packaging/setup_rpm.sh b/packages/google-compute-engine/packaging/setup_rpm.sh
index d98c2aa..8f5dfa9 100755
--- a/packages/google-compute-engine/packaging/setup_rpm.sh
+++ b/packages/google-compute-engine/packaging/setup_rpm.sh
@@ -14,7 +14,7 @@
# limitations under the License.
NAME="google-compute-engine"
-VERSION="2.8.14"
+VERSION="2.8.15"
rpm_working_dir=/tmp/rpmpackage/${NAME}-${VERSION}
working_dir=${PWD}
@@ -23,10 +23,6 @@ if [[ $(basename "$working_dir") != $NAME ]]; then
exit 1
fi
-# Build dependencies.
-sudo yum -y install make gcc-c++ libcurl-devel json-c json-c-devel pam-devel \
- policycoreutils-python boost-devel
-
# RPM creation tools.
sudo yum -y install rpmdevtools
diff --git a/packages/google-compute-engine/src/lib/systemd/system/google-accounts-daemon.service b/packages/google-compute-engine/src/lib/systemd/system/google-accounts-daemon.service
index 8ea5573..9158be5 100644
--- a/packages/google-compute-engine/src/lib/systemd/system/google-accounts-daemon.service
+++ b/packages/google-compute-engine/src/lib/systemd/system/google-accounts-daemon.service
@@ -7,6 +7,7 @@ Requires=network.target
Type=simple
ExecStart=/usr/bin/google_accounts_daemon
OOMScoreAdjust=-999
+Restart=always
[Install]
WantedBy=multi-user.target
diff --git a/packages/google-compute-engine/src/usr/bin/google_set_multiqueue b/packages/google-compute-engine/src/usr/bin/google_set_multiqueue
index 9dfe45f..7064a6b 100755
--- a/packages/google-compute-engine/src/usr/bin/google_set_multiqueue
+++ b/packages/google-compute-engine/src/usr/bin/google_set_multiqueue
@@ -125,10 +125,16 @@ for q in $XPS; do
xps=$((xps | (1 << cpu)))
done
- # Linux xps_cpus requires a hex number with commas every 32 bits.
- # It ignores all bits above # cpus, so unconditionally write a
- # 64 bit hex value, with a comma between dwords.
- xps_string=`printf "%08x,%08x" $((xps >> 32 & 0xffffffff)) $((xps & 0xffffffff))`
+ # Linux xps_cpus requires a hex number with commas every 32 bits. It ignores
+ # all bits above # cpus, so write a list of comma separated 32 bit hex values
+ # with a comma between dwords.
+ xps_dwords=()
+ for i in $(seq 0 $(((num_cpus - 1) / 32)))
+ do
+ xps_dwords+=(`printf "%08x" $((xps & 0xffffffff))`)
+ done
+ xps_string=$(IFS=, ; echo "${xps_dwords[*]}")
+
echo ${xps_string} > $q
printf "Queue %d XPS=%s for %s\n" $queue_num `cat $q` $q
diff --git a/packages/python-google-compute-engine/README.md b/packages/python-google-compute-engine/README.md
index f1ffe8e..0bd6ddb 100644
--- a/packages/python-google-compute-engine/README.md
+++ b/packages/python-google-compute-engine/README.md
@@ -28,8 +28,6 @@ The Linux guest environment is made up of the following components:
based authentication.
* **Clock skew** daemon to keep the system clock in sync after VM start and
stop events.
-* **Disk expand** scripts to expand the VM root partition for CentOS 6,
- CentOS 7, RHEL 6, and RHEL 7 images.
* **Instance setup** scripts to execute VM configuration scripts during boot.
* **Network** daemon that handles network setup for multiple network interfaces
on boot and integrates network load balancing with
@@ -38,7 +36,7 @@ The Linux guest environment is made up of the following components:
shutdown.
The Linux guest environment is written in Python and is version agnostic
-between Python 2.6 and 3.5. There is complete unittest coverage for every Python
+between Python 2.6 and 3.7. There is complete unittest coverage for every Python
library and script. The design of various guest libraries, daemons, and scripts,
are detailed in the sections below.
diff --git a/packages/python-google-compute-engine/google_compute_engine/boto/tests/compute_auth_test.py b/packages/python-google-compute-engine/google_compute_engine/boto/tests/compute_auth_test.py
index 0c31052..93e55ae 100644
--- a/packages/python-google-compute-engine/google_compute_engine/boto/tests/compute_auth_test.py
+++ b/packages/python-google-compute-engine/google_compute_engine/boto/tests/compute_auth_test.py
@@ -15,11 +15,16 @@
"""Unittest for compute_auth.py module."""
-from google_compute_engine.boto import compute_auth
+import sys
+
from google_compute_engine.test_compat import mock
from google_compute_engine.test_compat import unittest
+if sys.version_info < (3, 0):
+ from google_compute_engine.boto import compute_auth
+
+@unittest.skipIf(sys.version_info > (3, 0), 'Skipping for python3.')
class ComputeAuthTest(unittest.TestCase):
def setUp(self):
diff --git a/packages/python-google-compute-engine/google_compute_engine/compat.py b/packages/python-google-compute-engine/google_compute_engine/compat.py
index eb69763..3d18c12 100644
--- a/packages/python-google-compute-engine/google_compute_engine/compat.py
+++ b/packages/python-google-compute-engine/google_compute_engine/compat.py
@@ -19,7 +19,7 @@ import logging
import subprocess
import sys
-if sys.version_info >= (3, 6):
+if sys.version_info >= (3, 7):
import distro
else:
import platform as distro
diff --git a/packages/python-google-compute-engine/google_compute_engine/constants.py b/packages/python-google-compute-engine/google_compute_engine/constants.py
index cfe87c4..d929baf 100644
--- a/packages/python-google-compute-engine/google_compute_engine/constants.py
+++ b/packages/python-google-compute-engine/google_compute_engine/constants.py
@@ -16,6 +16,7 @@
"""A module for global constants."""
import platform
+import sys
OSLOGIN_CONTROL_SCRIPT = 'google_oslogin_control'
OSLOGIN_NSS_CACHE_SCRIPT = 'google_oslogin_nss_cache'
@@ -41,3 +42,8 @@ else:
OSLOGIN_NSS_CACHE = '/etc/oslogin_passwd.cache'
SYSCONFDIR = '/etc/default'
SYSLOG_SOCKET = '/dev/log'
+
+if sys.version_info >= (3, 0):
+ SET_BOTO_CONFIG = 'false'
+else:
+ SET_BOTO_CONFIG = 'true'
diff --git a/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_config.py b/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_config.py
index 1c23171..2326115 100644
--- a/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_config.py
+++ b/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_config.py
@@ -78,7 +78,7 @@ class InstanceConfig(config_manager.ConfigManager):
'host_key_types': 'ecdsa,ed25519,rsa',
'optimize_local_ssd': 'true',
'network_enabled': 'true',
- 'set_boto_config': 'true',
+ 'set_boto_config': constants.SET_BOTO_CONFIG,
'set_host_keys': 'true',
'set_multiqueue': 'true',
},
diff --git a/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_setup.py b/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_setup.py
index 80785e9..e72534c 100755
--- a/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_setup.py
+++ b/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_setup.py
@@ -28,9 +28,21 @@ from google_compute_engine import file_utils
from google_compute_engine import logger
from google_compute_engine import metadata_watcher
from google_compute_engine.boto import boto_config
+from google_compute_engine.compat import urlerror
+from google_compute_engine.compat import urlrequest
from google_compute_engine.instance_setup import instance_config
+class PutRequest(urlrequest.Request):
+ def get_method(self):
+ return 'PUT'
+
+
+GUEST_ATTRIBUTES_URL = ('http://metadata.google.internal/computeMetadata/v1beta1/'
+ 'instance/guest-attributes')
+HOSTKEY_NAMESPACE = 'hostkeys'
+
+
class InstanceSetup(object):
"""Initialize the instance the first time it boots."""
@@ -122,6 +134,9 @@ class InstanceSetup(object):
Args:
key_type: string, the type of the SSH key.
key_dest: string, a file location to store the SSH key.
+
+ Returns:
+ tuple, key_type and public key string.
"""
# Create a temporary file to save the created RSA keys.
with tempfile.NamedTemporaryFile(prefix=key_type, delete=True) as temp:
@@ -140,6 +155,28 @@ class InstanceSetup(object):
file_utils.SetPermissions(key_dest, mode=0o600)
file_utils.SetPermissions('%s.pub' % key_dest, mode=0o644)
+ with open('%s.pub' % key_dest, 'r') as pk:
+ key_data = pk.read()
+
+ key_values = key_data.split()
+ if len(key_values) < 2:
+ self.logger.warning('Could not read host key from %s.pub.', key_dest)
+ return
+ else:
+ return key_values[0], key_values[1]
+
+ def _WriteHostKeyToGuestAttributes(self, key_type, key_value):
+ """Write a host key to guest attributes, ignoring errors."""
+ headers = {'Metadata-Flavor': 'Google'}
+ url = '%s/%s/%s' % (GUEST_ATTRIBUTES_URL, HOSTKEY_NAMESPACE, key_type)
+ req = PutRequest(url, key_value, headers)
+ try:
+ response = urlrequest.urlopen(req)
+ self.logger.debug(response)
+ self.logger.info('Wrote %s host key to guest attributes.', key_type)
+ except urlerror.HTTPError:
+ self.logger.info('Unable to write %s host key to guest attributes.',
+ key_type)
def _StartSshd(self):
"""Initialize the SSH daemon."""
@@ -180,7 +217,9 @@ class InstanceSetup(object):
for key_file in set(key_files) | set(key_types_files):
key_type = file_regex.match(key_file).group('type')
key_dest = os.path.join(key_dir, key_file)
- self._GenerateSshKey(key_type, key_dest)
+ key_data = self._GenerateSshKey(key_type, key_dest)
+ if key_data:
+ self._WriteHostKeyToGuestAttributes(key_data[0], key_data[1])
self._StartSshd()
self.instance_config.SetOption(section, 'instance_id', str(instance_id))
diff --git a/packages/python-google-compute-engine/google_compute_engine/instance_setup/tests/instance_setup_test.py b/packages/python-google-compute-engine/google_compute_engine/instance_setup/tests/instance_setup_test.py
index 97a4674..a59ae0c 100644
--- a/packages/python-google-compute-engine/google_compute_engine/instance_setup/tests/instance_setup_test.py
+++ b/packages/python-google-compute-engine/google_compute_engine/instance_setup/tests/instance_setup_test.py
@@ -18,6 +18,7 @@
import subprocess
from google_compute_engine.instance_setup import instance_setup
+from google_compute_engine.test_compat import builtin
from google_compute_engine.test_compat import mock
from google_compute_engine.test_compat import unittest
@@ -231,22 +232,33 @@ class InstanceSetupTest(unittest.TestCase):
temp_dest = '/tmp/dest'
mock_tempfile.return_value = mock_tempfile
mock_tempfile.__enter__.return_value.name = temp_dest
-
- instance_setup.InstanceSetup._GenerateSshKey(
- self.mock_setup, key_type, key_dest)
- expected_calls = [
- mock.call.tempfile(prefix=key_type, delete=True),
- mock.call.tempfile.__enter__(),
- mock.call.tempfile.__exit__(None, None, None),
- mock.call.logger.info(mock.ANY, key_dest),
- mock.call.call(
- ['ssh-keygen', '-t', key_type, '-f', temp_dest, '-N', '', '-q']),
- mock.call.move(temp_dest, key_dest),
- mock.call.move('%s.pub' % temp_dest, '%s.pub' % key_dest),
- mock.call.permissions(key_dest, mode=0o600),
- mock.call.permissions('%s.pub' % key_dest, mode=0o644),
- ]
- self.assertEqual(mocks.mock_calls, expected_calls)
+ mock_open = mock.mock_open()
+ key_file_contents = 'ssh-rsa asdfasdf'
+ expected_key_data = ('ssh-rsa', 'asdfasdf')
+
+ with mock.patch('%s.open' % builtin, mock_open, create=False):
+ mock_open().read.return_value = key_file_contents
+ key_data = instance_setup.InstanceSetup._GenerateSshKey(
+ self.mock_setup, key_type, key_dest)
+ expected_calls = [
+ mock.call.tempfile(prefix=key_type, delete=True),
+ mock.call.tempfile.__enter__(),
+ mock.call.tempfile.__exit__(None, None, None),
+ mock.call.logger.info(mock.ANY, key_dest),
+ mock.call.call(
+ ['ssh-keygen', '-t', key_type, '-f', temp_dest, '-N', '', '-q']),
+ mock.call.move(temp_dest, key_dest),
+ mock.call.move('%s.pub' % temp_dest, '%s.pub' % key_dest),
+ mock.call.permissions(key_dest, mode=0o600),
+ mock.call.permissions('%s.pub' % key_dest, mode=0o644),
+ ]
+ self.assertEqual(mocks.mock_calls, expected_calls)
+ self.assertEqual(key_data, expected_key_data)
+
+ mock_open().read.return_value = ''
+ key_data = instance_setup.InstanceSetup._GenerateSshKey(
+ self.mock_setup, key_type, key_dest)
+ self.assertEqual(key_data, None)
@mock.patch('google_compute_engine.instance_setup.instance_setup.subprocess.check_call')
def testGenerateSshKeyProcessError(self, mock_call):
@@ -318,6 +330,32 @@ class InstanceSetupTest(unittest.TestCase):
instance_setup.InstanceSetup._SetSshHostKeys(self.mock_setup)
self.mock_instance_config.SetOption.assert_not_called()
+ @mock.patch('google_compute_engine.instance_setup.instance_setup.urlrequest.urlopen')
+ @mock.patch('google_compute_engine.instance_setup.instance_setup.PutRequest')
+ def testWriteHostKeyToGuestAttributes(self, mock_put, mock_urlopen):
+ key_type = 'ssh-rsa'
+ key_value = 'asdfasdf'
+ expected_url = ('http://metadata.google.internal/computeMetadata/v1beta1/'
+ 'instance/guest-attributes/hostkeys/%s' % key_type)
+ headers = {'Metadata-Flavor': 'Google'}
+
+ instance_setup.InstanceSetup._WriteHostKeyToGuestAttributes(
+ self.mock_setup, key_type, key_value)
+ self.mock_logger.info.assert_called_with(
+ 'Wrote %s host key to guest attributes.', key_type)
+ mock_put.assert_called_with(expected_url, key_value, headers)
+
+ mock_urlopen.side_effect = instance_setup.urlerror.HTTPError(
+ 'http://foo', 403, 'Forbidden', {}, None)
+ instance_setup.InstanceSetup._WriteHostKeyToGuestAttributes(
+ self.mock_setup, key_type, key_value)
+ self.mock_logger.info.assert_called_with(
+ 'Unable to write %s host key to guest attributes.', key_type)
+
+ def testPutRequest(self):
+ put_request = instance_setup.PutRequest('http://example.com/')
+ self.assertEqual(put_request.get_method(), 'PUT')
+
@mock.patch('google_compute_engine.instance_setup.instance_setup.os.listdir')
def testSetSshHostKeysFirstBoot(self, mock_listdir):
self.mock_instance_config.GetOptionString.return_value = None
@@ -325,6 +363,7 @@ class InstanceSetupTest(unittest.TestCase):
mock_instance_id.return_value = '123'
self.mock_setup._GetInstanceId = mock_instance_id
mock_generate_key = mock.Mock()
+ mock_generate_key.return_value = ('ssh-rsa', 'asdfasdf')
self.mock_setup._GenerateSshKey = mock_generate_key
mock_listdir.return_value = [
'ssh_config',
@@ -344,6 +383,7 @@ class InstanceSetupTest(unittest.TestCase):
mock.call('ed25519', '/etc/ssh/ssh_host_ed25519_key'),
mock.call('rsa', '/etc/ssh/ssh_host_rsa_key'),
]
+
self.assertEqual(sorted(mock_generate_key.mock_calls), expected_calls)
self.mock_instance_config.SetOption.assert_called_once_with(
'Instance', 'instance_id', '123')
diff --git a/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_retriever.py b/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_retriever.py
index c678f99..c880f49 100644
--- a/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_retriever.py
+++ b/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_retriever.py
@@ -15,11 +15,11 @@
"""Retrieve and store user provided metadata scripts."""
-import ast
+import functools
import re
import socket
-import subprocess
import tempfile
+import time
from google_compute_engine import metadata_watcher
from google_compute_engine.compat import httpclient
@@ -28,6 +28,37 @@ from google_compute_engine.compat import urlrequest
from google_compute_engine.compat import urlretrieve
+def _RetryOnUnavailable(func):
+ """Function decorator template to retry on a service unavailable exception."""
+
+ @functools.wraps(func)
+ def Wrapper(*args, **kwargs):
+ final_exception = None
+ for _ in range(3):
+ try:
+ response = func(*args, **kwargs)
+ except (httpclient.HTTPException, socket.error, urlerror.URLError) as e:
+ final_exception = e
+ time.sleep(5)
+ continue
+ else:
+ return response
+ raise final_exception
+ return Wrapper
+
+
+@_RetryOnUnavailable
+def _UrlOpenWithRetry(request):
+ """Call urlopen with retry."""
+ return urlrequest.urlopen(request)
+
+
+@_RetryOnUnavailable
+def _UrlRetrieveWithRetry(url, dest):
+ """Call urlretrieve with retry."""
+ return urlretrieve.urlretrieve(url, dest)
+
+
class ScriptRetriever(object):
"""A class for retrieving and storing user provided metadata scripts."""
token_metadata_key = 'instance/service-accounts/default/token'
@@ -81,12 +112,12 @@ class ScriptRetriever(object):
request = urlrequest.Request(url)
request.add_unredirected_header('Metadata-Flavor', 'Google')
request.add_unredirected_header('Authorization', self.token)
- content = urlrequest.urlopen(request).read().decode('utf-8')
- except (httpclient.HTTPException, socket.error, urlerror.URLError) as e:
+ content = _UrlOpenWithRetry(request).read().decode('utf-8')
+ except Exception as e:
self.logger.warning('Could not download %s. %s.', url, str(e))
return None
- with open(dest, 'wb') as f:
+ with open(dest, 'w') as f:
f.write(content)
return dest
@@ -107,7 +138,7 @@ class ScriptRetriever(object):
self.logger.info('Downloading url from %s to %s.', url, dest)
try:
- urlretrieve.urlretrieve(url, dest)
+ _UrlRetrieveWithRetry(url, dest)
return dest
except (httpclient.HTTPException, socket.error, urlerror.URLError) as e:
self.logger.warning('Could not download %s. %s.', url, str(e))
@@ -192,8 +223,10 @@ class ScriptRetriever(object):
metadata_value = attribute_data.get(metadata_key)
if metadata_value:
self.logger.info('Found %s in metadata.', metadata_key)
- script_dict[metadata_key] = self._DownloadScript(
- metadata_value, dest_dir)
+ downloaded_dest = self._DownloadScript(metadata_value, dest_dir)
+ if downloaded_dest is None:
+ self.logger.warning('Failed to download metadata script.')
+ script_dict[metadata_key] = downloaded_dest
return script_dict
diff --git a/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/tests/script_retriever_test.py b/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/tests/script_retriever_test.py
index f3f520a..b9d9d1b 100644
--- a/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/tests/script_retriever_test.py
+++ b/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/tests/script_retriever_test.py
@@ -19,7 +19,6 @@ import subprocess
from google_compute_engine.compat import urlerror
from google_compute_engine.metadata_scripts import script_retriever
-from google_compute_engine.metadata_watcher import MetadataWatcher
from google_compute_engine.test_compat import builtin
from google_compute_engine.test_compat import mock
from google_compute_engine.test_compat import unittest
@@ -63,7 +62,7 @@ class ScriptRetrieverTest(unittest.TestCase):
urlopen_read = mock_urlopen().read(return_value=b'foo').decode()
self.mock_logger.warning.assert_not_called()
- mock_open.assert_called_once_with(self.dest, 'wb')
+ mock_open.assert_called_once_with(self.dest, 'w')
handle = mock_open()
handle.write.assert_called_once_with(urlopen_read)
@@ -145,16 +144,42 @@ class ScriptRetrieverTest(unittest.TestCase):
mock_retrieve.assert_called_once_with(url, self.dest)
self.mock_logger.warning.assert_not_called()
+ @mock.patch('google_compute_engine.metadata_scripts.script_retriever.time')
@mock.patch('google_compute_engine.metadata_scripts.script_retriever.tempfile.NamedTemporaryFile')
@mock.patch('google_compute_engine.metadata_scripts.script_retriever.urlretrieve.urlretrieve')
- def testDownloadUrlProcessError(self, mock_retrieve, mock_tempfile):
+ def testDownloadUrlProcessError(self, mock_retrieve, mock_tempfile, mock_time):
url = 'http://www.google.com/fake/url'
mock_tempfile.return_value = mock_tempfile
mock_tempfile.name = self.dest
- mock_retrieve.side_effect = script_retriever.socket.timeout()
+ mock_success = mock.Mock()
+ mock_success.getcode.return_value = script_retriever.httpclient.OK
+ # Success after 3 timeout. Since max_retry = 3, the final result is fail.
+ mock_retrieve.side_effect = [
+ script_retriever.socket.timeout(),
+ script_retriever.socket.timeout(),
+ script_retriever.socket.timeout(),
+ mock_success,
+ ]
self.assertIsNone(self.retriever._DownloadUrl(url, self.dest_dir))
self.assertEqual(self.mock_logger.warning.call_count, 1)
+ @mock.patch('google_compute_engine.metadata_scripts.script_retriever.time')
+ @mock.patch('google_compute_engine.metadata_scripts.script_retriever.tempfile.NamedTemporaryFile')
+ @mock.patch('google_compute_engine.metadata_scripts.script_retriever.urlretrieve.urlretrieve')
+ def testDownloadUrlWithRetry(self, mock_retrieve, mock_tempfile, mock_time):
+ url = 'http://www.google.com/fake/url'
+ mock_tempfile.return_value = mock_tempfile
+ mock_tempfile.name = self.dest
+ mock_success = mock.Mock()
+ mock_success.getcode.return_value = script_retriever.httpclient.OK
+ # Success after 2 timeout. Since max_retry = 3, the final result is success.
+ mock_retrieve.side_effect = [
+ script_retriever.socket.timeout(),
+ script_retriever.socket.timeout(),
+ mock_success,
+ ]
+ self.assertIsNotNone(self.retriever._DownloadUrl(url, self.dest_dir))
+
@mock.patch('google_compute_engine.metadata_scripts.script_retriever.tempfile.NamedTemporaryFile')
@mock.patch('google_compute_engine.metadata_scripts.script_retriever.urlretrieve.urlretrieve')
def testDownloadUrlException(self, mock_retrieve, mock_tempfile):
@@ -325,6 +350,7 @@ class ScriptRetrieverTest(unittest.TestCase):
self.assertEqual(self.retriever.GetScripts(self.dest_dir), expected_data)
self.assertEqual(self.mock_logger.info.call_count, 2)
+ self.assertEqual(self.mock_logger.warning.call_count, 0)
mock_dest.write.assert_called_once_with('a')
mock_download.assert_called_once_with('b', self.dest_dir)
@@ -352,6 +378,44 @@ class ScriptRetrieverTest(unittest.TestCase):
self.mock_logger.info.assert_not_called()
self.assertEqual(self.mock_logger.warning.call_count, 2)
+ @mock.patch('google_compute_engine.metadata_scripts.script_retriever.tempfile.NamedTemporaryFile')
+ def testGetScriptsFailed(self, mock_tempfile):
+ script_dest = '/tmp/script'
+ script_url_dest = None
+ metadata = {
+ 'instance': {
+ 'attributes': {
+ '%s-script' % self.script_type: 'a',
+ '%s-script-url' % self.script_type: 'b',
+ },
+ },
+ 'project': {
+ 'attributes': {
+ '%s-script' % self.script_type: 'c',
+ '%s-script-url' % self.script_type: 'd',
+ },
+ },
+ }
+ expected_data = {
+ '%s-script' % self.script_type: script_dest,
+ '%s-script-url' % self.script_type: script_url_dest,
+ }
+ self.mock_watcher.GetMetadata.return_value = metadata
+ self.retriever.watcher = self.mock_watcher
+ # Mock saving a script to a file.
+ mock_dest = mock.Mock()
+ mock_dest.name = script_dest
+ mock_tempfile.__enter__.return_value = mock_dest
+ mock_tempfile.return_value = mock_tempfile
+ # Mock downloading a script from a URL.
+ mock_download = mock.Mock()
+ mock_download.return_value = None
+ self.retriever._DownloadScript = mock_download
+
+ self.assertEqual(self.retriever.GetScripts(self.dest_dir), expected_data)
+ self.assertEqual(self.mock_logger.info.call_count, 2)
+ self.assertEqual(self.mock_logger.warning.call_count, 1)
+
if __name__ == '__main__':
unittest.main()
diff --git a/packages/python-google-compute-engine/packaging/debian/changelog b/packages/python-google-compute-engine/packaging/debian/changelog
index 822bcb9..1567ac1 100644
--- a/packages/python-google-compute-engine/packaging/debian/changelog
+++ b/packages/python-google-compute-engine/packaging/debian/changelog
@@ -1,3 +1,12 @@
+python-google-compute-engine (2.8.15-1) stable; urgency=low
+
+ * Retry download for metadata scripts.
+ * Fix script retrieval in python3.
+ * Disable boto config in python3.
+ * Update SSH host keys in guest attributes.
+
+ -- Google Cloud Team <gc-team@google.com> Tue, 21 May 2019 12:00:00 -0700
+
python-google-compute-engine (2.8.14-1) stable; urgency=low
* FreeBSD fixes: syslog socket location and OS detection.
diff --git a/packages/python-google-compute-engine/packaging/python3-google-compute-engine.spec b/packages/python-google-compute-engine/packaging/python3-google-compute-engine.spec
new file mode 100644
index 0000000..6bf3291
--- /dev/null
+++ b/packages/python-google-compute-engine/packaging/python3-google-compute-engine.spec
@@ -0,0 +1,47 @@
+# Copyright 2019 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.
+
+Name: python3-google-compute-engine
+Version: %{_version}
+Release: 1%{?dist}
+Summary: Google Compute Engine python3 library
+License: ASL 2.0
+Url: https://github.com/GoogleCloudPlatform/compute-image-packages
+Source0: %{name}_%{version}.orig.tar.gz
+
+BuildArch: noarch
+BuildRequires: python36-devel python3-setuptools
+
+Requires: python3-setuptools
+
+%description
+Google Compute Engine python library for Python 3.x.
+
+%prep
+%autosetup
+
+%build
+%py3_build
+
+%install
+%py3_install
+
+%files
+%{python3_sitelib}/google_compute_engine/
+%{python3_sitelib}/google_compute_engine*.egg-info/
+%{_bindir}/google_accounts_daemon
+%{_bindir}/google_clock_skew_daemon
+%{_bindir}/google_instance_setup
+%{_bindir}/google_metadata_script_runner
+%{_bindir}/google_network_daemon
diff --git a/packages/python-google-compute-engine/packaging/setup_deb.sh b/packages/python-google-compute-engine/packaging/setup_deb.sh
index b47c54d..e3149a3 100755
--- a/packages/python-google-compute-engine/packaging/setup_deb.sh
+++ b/packages/python-google-compute-engine/packaging/setup_deb.sh
@@ -14,7 +14,7 @@
# limitations under the License.
NAME="python-google-compute-engine"
-VERSION="2.8.14"
+VERSION="2.8.15"
working_dir=${PWD}
if [[ $(basename "$working_dir") != $NAME ]]; then
diff --git a/packages/python-google-compute-engine/packaging/setup_rpm.sh b/packages/python-google-compute-engine/packaging/setup_rpm.sh
index d1eccc3..99c217f 100755
--- a/packages/python-google-compute-engine/packaging/setup_rpm.sh
+++ b/packages/python-google-compute-engine/packaging/setup_rpm.sh
@@ -14,7 +14,7 @@
# limitations under the License.
NAME="python-google-compute-engine"
-VERSION="2.8.14"
+VERSION="2.8.15"
rpm_working_dir=/tmp/rpmpackage/${NAME}-${VERSION}
working_dir=${PWD}
@@ -23,12 +23,17 @@ if [[ $(basename "$working_dir") != $NAME ]]; then
exit 1
fi
-# Build dependencies.
-sudo yum -y install python2-devel python-setuptools python-boto
-
-# RPM creation tools.
sudo yum -y install rpmdevtools
+# RHEL/CentOS 8 uses python3.
+if grep -q '^\(CentOS\|Red Hat\)[^0-9]*8\..' /etc/redhat-release; then
+ NAME="python3-google-compute-engine"
+ rpm_working_dir=/tmp/rpmpackage/${NAME}-${VERSION}
+ sudo yum -y install python36-devel python3-setuptools python36-rpm-macros
+else
+ sudo yum -y install python2-devel python-setuptools python-boto
+fi
+
rm -rf /tmp/rpmpackage
mkdir -p ${rpm_working_dir}/{SOURCES,SPECS}
diff --git a/packages/python-google-compute-engine/setup.py b/packages/python-google-compute-engine/setup.py
index 59a61b3..a91beec 100755
--- a/packages/python-google-compute-engine/setup.py
+++ b/packages/python-google-compute-engine/setup.py
@@ -20,8 +20,10 @@ import sys
import setuptools
-install_requires = ['boto', 'setuptools']
-if sys.version_info >= (3, 6):
+install_requires = ['setuptools']
+if sys.version_info < (3, 0):
+ install_requires += ['boto']
+if sys.version_info >= (3, 7):
install_requires += ['distro']
setuptools.setup(
@@ -35,7 +37,7 @@ setuptools.setup(
name='google-compute-engine',
packages=setuptools.find_packages(),
url='https://github.com/GoogleCloudPlatform/compute-image-packages',
- version='2.8.13',
+ version='2.8.15',
# Entry points create scripts in /usr/bin that call a function.
entry_points={
'console_scripts': [