diff -Nru gce-compute-image-packages-20190315/daisy_workflows/build_el.wf.json gce-compute-image-packages-20190521/daisy_workflows/build_el.wf.json --- gce-compute-image-packages-20190315/daisy_workflows/build_el.wf.json 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/daisy_workflows/build_el.wf.json 2019-05-21 20:40:07.000000000 +0000 @@ -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 -Nru gce-compute-image-packages-20190315/debian/changelog gce-compute-image-packages-20190521/debian/changelog --- gce-compute-image-packages-20190315/debian/changelog 2019-04-22 12:13:57.000000000 +0000 +++ gce-compute-image-packages-20190521/debian/changelog 2019-05-23 11:29:21.000000000 +0000 @@ -1,3 +1,32 @@ +gce-compute-image-packages (20190521-0ubuntu1~16.04.0) xenial; urgency=medium + + * Backport to Xenial with the following remaining changes: + - Revert ordering shutdown scripts after snapd.service. + - Revert adding /snap/bin to PATH for startup/shutdown scripts + - Revert to using dh-systemd because Xenial does not have the debhelper + - Build-depend on libboost-regex-dev for regex support + version making dh-systemd obsolete + - Link with boost for regex support + - Free tests from C++11 constructs to let them being compiled without + C++11 support + + -- Balint Reczey Thu, 23 May 2019 13:29:21 +0200 + +gce-compute-image-packages (20190521-0ubuntu1) eoan; urgency=medium + + * New upstream version 20190521 (LP: #1830194) + - Fix pam_group ordering detection + - Restart cron on OS Login control + - Add PAM entry to su:account stack + - Retry download for metadata scripts + - Fix script retrieval in python3 + - Disable boto config in python3 + - Update SSH host keys in guest attributes. + - Fix XPS settings with more than 64 vCPUs + * Update shared library symlinks + + -- Balint Reczey Wed, 22 May 2019 18:53:01 +0200 + gce-compute-image-packages (20190315-0ubuntu1~16.04.0) xenial; urgency=medium * Backport to Xenial with the following remaining changes: diff -Nru gce-compute-image-packages-20190315/debian/google-compute-engine-oslogin.links gce-compute-image-packages-20190521/debian/google-compute-engine-oslogin.links --- gce-compute-image-packages-20190315/debian/google-compute-engine-oslogin.links 2019-04-22 12:13:57.000000000 +0000 +++ gce-compute-image-packages-20190521/debian/google-compute-engine-oslogin.links 2019-05-23 11:29:21.000000000 +0000 @@ -1,2 +1,2 @@ -lib/libnss_cache_google-compute-engine-oslogin-1.5.1.so lib/libnss_cache_oslogin.so.2 -lib/libnss_google-compute-engine-oslogin-1.5.1.so lib/libnss_oslogin.so.2 +lib/libnss_cache_google-compute-engine-oslogin-1.5.2.so lib/libnss_cache_oslogin.so.2 +lib/libnss_google-compute-engine-oslogin-1.5.2.so lib/libnss_oslogin.so.2 diff -Nru gce-compute-image-packages-20190315/packages/gce-disk-expand/packaging/gce-disk-expand.spec gce-compute-image-packages-20190521/packages/gce-disk-expand/packaging/gce-disk-expand.spec --- gce-compute-image-packages-20190315/packages/gce-disk-expand/packaging/gce-disk-expand.spec 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/gce-disk-expand/packaging/gce-disk-expand.spec 2019-05-21 20:40:07.000000000 +0000 @@ -33,13 +33,13 @@ %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 -Nru gce-compute-image-packages-20190315/packages/gce-disk-expand/packaging/setup_deb.sh gce-compute-image-packages-20190521/packages/gce-disk-expand/packaging/setup_deb.sh --- gce-compute-image-packages-20190315/packages/gce-disk-expand/packaging/setup_deb.sh 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/gce-disk-expand/packaging/setup_deb.sh 2019-05-21 20:40:07.000000000 +0000 @@ -26,7 +26,7 @@ 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 -Nru gce-compute-image-packages-20190315/packages/gce-disk-expand/packaging/setup_rpm.sh gce-compute-image-packages-20190521/packages/gce-disk-expand/packaging/setup_rpm.sh --- gce-compute-image-packages-20190315/packages/gce-disk-expand/packaging/setup_rpm.sh 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/gce-disk-expand/packaging/setup_rpm.sh 2019-05-21 20:40:07.000000000 +0000 @@ -24,7 +24,7 @@ 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 -Nru gce-compute-image-packages-20190315/packages/gce-disk-expand/src/expandfs-lib.sh gce-compute-image-packages-20190521/packages/gce-disk-expand/src/expandfs-lib.sh --- gce-compute-image-packages-20190315/packages/gce-disk-expand/src/expandfs-lib.sh 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/gce-disk-expand/src/expandfs-lib.sh 2019-05-21 20:40:07.000000000 +0000 @@ -24,7 +24,7 @@ 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 @@ 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 @@ return 1 fi done + udevadm settle ) diff -Nru gce-compute-image-packages-20190315/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs_dummy.sh gce-compute-image-packages-20190521/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs_dummy.sh --- gce-compute-image-packages-20190315/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs_dummy.sh 1970-01-01 00:00:00.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs_dummy.sh 2019-05-21 20:40:07.000000000 +0000 @@ -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 -Nru gce-compute-image-packages-20190315/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh gce-compute-image-packages-20190521/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh --- gce-compute-image-packages-20190315/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/expand_rootfs.sh 2019-05-21 20:40:07.000000000 +0000 @@ -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 @@ 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 @@ fi fi - udevsettle - if ! out=$(resize_filesystem "$rootdev"); then echo "Failed to resize filesystem: ${out}" return diff -Nru gce-compute-image-packages-20190315/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install gce-compute-image-packages-20190521/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install --- gce-compute-image-packages-20190315/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/install 2019-05-21 20:40:07.000000000 +0000 @@ -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 grep dracut_install resize2fs dracut_install e2fsck +dracut_install udevadm dracut_install -o xfs_growfs diff -Nru gce-compute-image-packages-20190315/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/xfs_growfs.sh gce-compute-image-packages-20190521/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/xfs_growfs.sh --- gce-compute-image-packages-20190315/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/xfs_growfs.sh 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/gce-disk-expand/src/usr/share/dracut/modules.d/50expand_rootfs/xfs_growfs.sh 2019-05-21 20:40:07.000000000 +0000 @@ -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 @@ 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 -Nru gce-compute-image-packages-20190315/packages/google-compute-engine/packaging/debian/changelog gce-compute-image-packages-20190521/packages/google-compute-engine/packaging/debian/changelog --- gce-compute-image-packages-20190315/packages/google-compute-engine/packaging/debian/changelog 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine/packaging/debian/changelog 2019-05-21 20:40:07.000000000 +0000 @@ -1,3 +1,15 @@ +google-compute-engine (2.8.15-1) stable; urgency=low + + * Fix XPS settings with more than 64 vCPUs. + + -- Google Cloud Team 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. + + -- Google Cloud Team Tue, 16 Apr 2019 12:00:00 -0700 + google-compute-engine (2.8.13-1) stable; urgency=low * Fix metadata script retrieval to support Python 3. diff -Nru gce-compute-image-packages-20190315/packages/google-compute-engine/packaging/google-compute-engine.spec gce-compute-image-packages-20190521/packages/google-compute-engine/packaging/google-compute-engine.spec --- gce-compute-image-packages-20190315/packages/google-compute-engine/packaging/google-compute-engine.spec 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine/packaging/google-compute-engine.spec 2019-05-21 20:40:07.000000000 +0000 @@ -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 -Nru gce-compute-image-packages-20190315/packages/google-compute-engine/packaging/setup_deb.sh gce-compute-image-packages-20190521/packages/google-compute-engine/packaging/setup_deb.sh --- gce-compute-image-packages-20190315/packages/google-compute-engine/packaging/setup_deb.sh 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine/packaging/setup_deb.sh 2019-05-21 20:40:07.000000000 +0000 @@ -14,7 +14,7 @@ # limitations under the License. NAME="google-compute-engine" -VERSION="2.8.13" +VERSION="2.8.15" working_dir=${PWD} if [[ $(basename "$working_dir") != $NAME ]]; then diff -Nru gce-compute-image-packages-20190315/packages/google-compute-engine/packaging/setup_rpm.sh gce-compute-image-packages-20190521/packages/google-compute-engine/packaging/setup_rpm.sh --- gce-compute-image-packages-20190315/packages/google-compute-engine/packaging/setup_rpm.sh 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine/packaging/setup_rpm.sh 2019-05-21 20:40:07.000000000 +0000 @@ -14,7 +14,7 @@ # limitations under the License. NAME="google-compute-engine" -VERSION="2.8.13" +VERSION="2.8.15" rpm_working_dir=/tmp/rpmpackage/${NAME}-${VERSION} working_dir=${PWD} @@ -23,10 +23,6 @@ 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 -Nru gce-compute-image-packages-20190315/packages/google-compute-engine/src/etc/init/google-startup-scripts.conf gce-compute-image-packages-20190521/packages/google-compute-engine/src/etc/init/google-startup-scripts.conf --- gce-compute-image-packages-20190315/packages/google-compute-engine/src/etc/init/google-startup-scripts.conf 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine/src/etc/init/google-startup-scripts.conf 2019-05-21 20:40:07.000000000 +0000 @@ -1,4 +1,4 @@ # Runs a startup script from metadata. -start on started google-network-daemon +start on started google-network-daemon and startup exec /usr/bin/google_metadata_script_runner --script-type startup diff -Nru gce-compute-image-packages-20190315/packages/google-compute-engine/src/lib/systemd/system/google-accounts-daemon.service gce-compute-image-packages-20190521/packages/google-compute-engine/src/lib/systemd/system/google-accounts-daemon.service --- gce-compute-image-packages-20190315/packages/google-compute-engine/src/lib/systemd/system/google-accounts-daemon.service 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine/src/lib/systemd/system/google-accounts-daemon.service 2019-05-21 20:40:07.000000000 +0000 @@ -7,6 +7,7 @@ Type=simple ExecStart=/usr/bin/google_accounts_daemon OOMScoreAdjust=-999 +Restart=always [Install] WantedBy=multi-user.target diff -Nru gce-compute-image-packages-20190315/packages/google-compute-engine/src/usr/bin/google_set_multiqueue gce-compute-image-packages-20190521/packages/google-compute-engine/src/usr/bin/google_set_multiqueue --- gce-compute-image-packages-20190315/packages/google-compute-engine/src/usr/bin/google_set_multiqueue 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine/src/usr/bin/google_set_multiqueue 2019-05-21 20:40:07.000000000 +0000 @@ -125,10 +125,16 @@ 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 -Nru gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/bin/google_oslogin_control gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/bin/google_oslogin_control --- gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/bin/google_oslogin_control 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/bin/google_oslogin_control 2019-05-21 20:40:07.000000000 +0000 @@ -14,7 +14,8 @@ # limitations under the License. nss_config="/etc/nsswitch.conf" -pam_config="/etc/pam.d/sshd" +pam_sshd_config="/etc/pam.d/sshd" +pam_su_config="/etc/pam.d/su" sshd_config="/etc/ssh/sshd_config" group_config="/etc/security/group.conf" sudoers_dir="/var/google-sudoers.d" @@ -125,16 +126,21 @@ } # Inserts pam modules to relevant pam stacks if missing. -modify_pam_sshd() ( +modify_pam_config() ( + # TODO: idempotency of this function would be better assured if it wiped out + # and applied desired changes each time rather than detecting deltas. + set -e - local pam_config="${1:-${pam_config}}" + local pam_sshd_config="${1:-${pam_sshd_config}}" + local pam_su_config="${1:-${pam_su_config}}" local pam_auth_oslogin="auth [success=done perm_denied=die default=ignore] pam_oslogin_login.so" local pam_auth_group="auth [default=ignore] pam_group.so" local pam_account_oslogin="account [success=ok default=ignore] pam_oslogin_admin.so" local pam_account_admin="account [success=ok ignore=ignore default=die] pam_oslogin_login.so" local pam_session_homedir="session [success=ok default=ignore] pam_mkhomedir.so" + local pam_account_su="account [success=bad ignore=ignore] pam_oslogin_login.so" # In FreeBSD, the used flags are not supported, replacing them with the # previous ones (requisite and optional). This is not an exact feature parity @@ -148,6 +154,7 @@ fi local added_config="" + local added_su_config="" # For COS this file is solely includes, so simply prepend the new config, # making each entry the top of its stack. @@ -155,70 +162,93 @@ added_config="${added_comment}\n" for cfg in "$pam_account_admin" "$pam_account_oslogin" \ "$pam_session_homedir" "$pam_auth_group"; do - grep -qE "^${cfg%% *}.*${cfg##* }" ${pam_config} || added_config="${added_config}${cfg}\n" + grep -qE "^${cfg%% *}.*${cfg##* }" ${pam_sshd_config} || added_config="${added_config}${cfg}\n" done if [ -n "$two_factor" ]; then - grep -q "$pam_auth_oslogin" "$pam_config" || added_config="${added_config}${pam_auth_oslogin}\n" + grep -q "$pam_auth_oslogin" "$pam_sshd_config" || added_config="${added_config}${pam_auth_oslogin}\n" fi - $sed -i"" "1i ${added_config}\n\n" "$pam_config" + $sed -i"" "1i ${added_config}\n\n" "$pam_sshd_config" + + added_su_config="${added_comment}\n${pam_account_su}" + $sed -i"" "1i ${added_su_config}" "$pam_su_config" return 0 fi - # Find the distro-specific insertion point for auth. + # Find the distro-specific insertion point for auth and su. if [ -e /etc/debian_version ]; then # Get location of common-auth and check if preceding line is a comment. - insert=$($sed -rn "/^@include\s+common-auth/=" "$pam_config") - $sed -n "$((insert-1))p" "$pam_config" | grep -q '^#' && insert=$((insert-1)) + insert=$($sed -rn "/^@include\s+common-auth/=" "$pam_sshd_config") + $sed -n "$((insert-1))p" "$pam_sshd_config" | grep -q '^#' && insert=$((insert-1)) + su_insert=$($sed -rn "/^@include\s+common-account/=" "$pam_su_config") elif [ -e /etc/redhat-release ]; then # Get location of password-auth. insert=$($sed -rn "/^auth\s+(substack|include)\s+password-auth/=" \ - "$pam_config") + "$pam_sshd_config") + # Get location of system-auth. + su_insert=$($sed -rn "/^account\s+include\s+system-auth/=" "$pam_su_config") elif [ -e /etc/os-release ] && grep -q 'ID="sles"' /etc/os-release; then # Get location of common-auth. - insert=$($sed -rn "/^auth\s+include\s+common-auth/=" "$pam_config") + insert=$($sed -rn "/^auth\s+include\s+common-auth/=" "$pam_sshd_config") + # Get location of common-account. + su_insert=$($sed -rn "/^account\s+include\s+common-account/=" "$pam_su_config") elif [ -e /etc/arch-release ]; then # Get location of system-remote-login. - insert=$($sed -rn "/^auth\s+include\s+system-remote-login/=" "$pam_config") + insert=$($sed -rn "/^auth\s+include\s+system-remote-login/=" "$pam_sshd_config") + # TODO: find su_insert point for arch linux. fi added_config="$added_comment" - if [ -n "$two_factor" ] && ! grep -qE '^auth.*oslogin' "$pam_config"; then - added_config="${added_config}\n${pam_auth_oslogin}" - fi - if ! grep -qE '^auth.*pam_group' "$pam_config"; then + if ! grep -qE '^auth.*pam_group' "$pam_sshd_config"; then added_config="${added_config}\n${pam_auth_group}" fi - # We can and should insert auth modules at top of `auth` stack. + # This auth entry for OS Login+two factor MUST be added last, as it will + # short-circuit processing of the auth stack via [success=ok]. auth stack + # entries after this one will not be processed. + if [ -n "$two_factor" ] && ! grep -qE '^auth.*oslogin' "$pam_sshd_config"; then + added_config="${added_config}\n${pam_auth_oslogin}" + fi + + # Insert auth modules at top of `sshd:auth` stack. if [ -n "$insert" ] && [ "$added_config" != "$added_comment" ]; then - $sed -i"" "${insert}i ${added_config}" "$pam_config" + $sed -i"" "${insert}i ${added_config}" "$pam_sshd_config" + fi + + # Insert su blocker at top of `su:account` stack. + if [ -n "$su_insert" ] && ! grep -qE "$pam_account_su" "$pam_su_config"; then + added_su_config="${added_comment}\n${pam_account_su}" + sed -i"" "${su_insert}i ${added_su_config}" "$pam_su_config" fi - # Append account modules at end of `account` stack. - if ! grep -qE '^account.*oslogin' "$pam_config"; then + # Append account modules at end of `sshd:account` stack. + if ! grep -qE '^account.*oslogin' "$pam_sshd_config"; then added_config="\\\n${added_comment}\n${pam_account_admin}\n${pam_account_oslogin}" - account_end=$($sed -n '/^account/=' "$pam_config" | tail -1) - $sed -i"" "${account_end}a ${added_config}" "$pam_config" + account_end=$($sed -n '/^account/=' "$pam_sshd_config" | tail -1) + $sed -i"" "${account_end}a ${added_config}" "$pam_sshd_config" fi - # Append mkhomedir module at end of `session` stack. - if ! grep -qE '^session.*mkhomedir' "$pam_config"; then + # Append mkhomedir module at end of `sshd:session` stack. + if ! grep -qE '^session.*mkhomedir' "$pam_sshd_config"; then added_config="\\\n${added_comment}\n${pam_session_homedir}" - session_end=$($sed -n '/^session/=' "$pam_config" | tail -1) - $sed -i"" "${session_end}a ${added_config}" "$pam_config" + session_end=$($sed -n '/^session/=' "$pam_sshd_config" | tail -1) + $sed -i"" "${session_end}a ${added_config}" "$pam_sshd_config" fi ) -restore_pam_sshd() { - local pam_config="${1:-${pam_config}}" +restore_pam_config() { + local pam_sshd_config="${1:-${pam_sshd_config}}" + local pam_su_config="${1:-${pam_su_config}}" + + $sed -i"" "/${added_comment}/d" "$pam_sshd_config" + $sed -i"" "/pam_oslogin/d" "$pam_sshd_config" + $sed -i"" "/^session.*mkhomedir/d" "$pam_sshd_config" + $sed -i"" "/^auth.*pam_group/d" "$pam_sshd_config" - $sed -i"" "/${added_comment}/d" "$pam_config" - $sed -i"" "/pam_oslogin/d" "$pam_config" - $sed -i"" "/^session.*mkhomedir/d" "$pam_config" - $sed -i"" "/^auth.*pam_group/d" "$pam_config" + $sed -i"" "/${added_comment}/d" "$pam_su_config" + $sed -i"" "/pam_oslogin/d" "$pam_su_config" } modify_group_conf() { @@ -288,7 +318,7 @@ restart_svcs() { echo "Restarting optional services." - for svc in "nscd" "unscd" "systemd-logind"; do + for svc in "nscd" "unscd" "systemd-logind" "cron" "crond"; do restart_service "$svc" done } @@ -315,7 +345,7 @@ activate() { for func in modify_sshd_conf modify_nsswitch_conf \ - modify_pam_sshd setup_google_dirs restart_svcs restart_sshd \ + modify_pam_config setup_google_dirs restart_svcs restart_sshd \ modify_group_conf; do $func [ $? -eq 0 ] || return 1 @@ -324,7 +354,7 @@ deactivate() { for func in remove_google_dirs restore_nsswitch_conf \ - restore_sshd_conf restore_pam_sshd restart_svcs restart_sshd \ + restore_sshd_conf restore_pam_config restart_svcs restart_sshd \ restore_group_conf; do $func done @@ -335,11 +365,11 @@ get_status() ( set -e - grep -Eq '^account.*oslogin' "$pam_config" + grep -Eq '^account.*oslogin' "$pam_sshd_config" grep -Eq 'google_authorized_keys' "$sshd_config" grep -Eq 'passwd:.*oslogin' "$nss_config" if [ -n "$two_factor" ]; then - grep -Eq '^auth.*oslogin' "$pam_config" + grep -Eq '^auth.*oslogin' "$pam_sshd_config" grep -Eq '^(AuthenticationMethods|RequiredAuthentications2).*publickey,keyboard-interactive' "$sshd_config" fi ) diff -Nru gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/Makefile gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/Makefile --- gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/Makefile 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/Makefile 2019-05-21 20:40:07.000000000 +0000 @@ -4,7 +4,7 @@ NAME = google-compute-engine-$(BASENAME) MAJOR = 1 MINOR = 5 -REVISION = 1 +REVISION = 2 LIBNSS_CACHE_OSLOGIN = libnss_cache_$(BASENAME) LIBNSS_CACHE_OSLOGIN_NAME = libnss_cache_$(NAME)-$(MAJOR).$(MINOR).$(REVISION).so diff -Nru gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/packaging/debian/changelog gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/packaging/debian/changelog --- gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/packaging/debian/changelog 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/packaging/debian/changelog 2019-05-21 20:40:07.000000000 +0000 @@ -1,3 +1,11 @@ +google-compute-engine-oslogin (1.5.2-1) unstable; urgency=low + + * Fix pam_group ordering detection. + * Restart cron on OS Login control. + * Add PAM entry to su:account stack. + + -- Google Cloud Team Tue, 16 Apr 2019 12:00:00 -0700 + google-compute-engine-oslogin (1.5.1-1) unstable; urgency=low * Fix two factor auth action name. diff -Nru gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/packaging/google-compute-engine-oslogin.spec gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/packaging/google-compute-engine-oslogin.spec --- gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/packaging/google-compute-engine-oslogin.spec 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/packaging/google-compute-engine-oslogin.spec 2019-05-21 20:40:07.000000000 +0000 @@ -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: 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 @@ 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 @@ %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 -Nru gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/packaging/setup_deb.sh gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/packaging/setup_deb.sh --- gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/packaging/setup_deb.sh 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/packaging/setup_deb.sh 2019-05-21 20:40:07.000000000 +0000 @@ -14,7 +14,7 @@ # limitations under the License. NAME="google-compute-engine-oslogin" -VERSION="1.5.1" +VERSION="1.5.2" working_dir=${PWD} if [[ $(basename "$working_dir") != $NAME ]]; then diff -Nru gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/packaging/setup_rpm.sh gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/packaging/setup_rpm.sh --- gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/packaging/setup_rpm.sh 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/packaging/setup_rpm.sh 2019-05-21 20:40:07.000000000 +0000 @@ -15,7 +15,7 @@ NAME="google-compute-engine-oslogin" -VERSION="1.5.1" +VERSION="1.5.2" rpm_working_dir=/tmp/rpmpackage/${NAME}-${VERSION} working_dir=${PWD} @@ -24,11 +24,14 @@ 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 -Nru gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/pam_module/pam_oslogin_login.cc gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/pam_module/pam_oslogin_login.cc --- gce-compute-image-packages-20190315/packages/google-compute-engine-oslogin/pam_module/pam_oslogin_login.cc 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/google-compute-engine-oslogin/pam_module/pam_oslogin_login.cc 2019-05-21 20:40:07.000000000 +0000 @@ -29,8 +29,6 @@ #include "../compat.h" #include "../utils/oslogin_utils.h" -using std::string; - using oslogin_utils::ContinueSession; using oslogin_utils::GetUser; using oslogin_utils::HttpGet; @@ -47,47 +45,49 @@ static const char kUsersDir[] = "/var/google-users.d/"; extern "C" { - PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) { - int pam_result = PAM_PERM_DENIED; const char *user_name; - if ((pam_result = pam_get_user(pamh, &user_name, NULL)) != PAM_SUCCESS) { + if (pam_get_user(pamh, &user_name, NULL) != PAM_SUCCESS) { PAM_SYSLOG(pamh, LOG_INFO, "Could not get pam user."); - return pam_result; + return PAM_AUTH_ERR; } - string str_user_name(user_name); + if (!ValidateUserName(user_name)) { - // If the user name is not a valid oslogin user, don't bother continuing. - return PAM_SUCCESS; + // Not a valid OS Login username. + return PAM_IGNORE; } - string users_filename = kUsersDir; + + std::string users_filename = kUsersDir; users_filename.append(user_name); struct stat buffer; bool file_exists = !stat(users_filename.c_str(), &buffer); + std::string str_user_name(user_name); std::stringstream url; url << kMetadataServerUrl << "users?username=" << UrlEncode(str_user_name); - string response; + + std::string response; long http_code = 0; if (!HttpGet(url.str(), &response, &http_code) || response.empty() || http_code != 200) { if (http_code == 404) { - // Return success on non-oslogin users. - return PAM_SUCCESS; + // This module is only consulted for OS Login users. + return PAM_IGNORE; } - // If we can't reliably tell if this is an oslogin user, check if there is - // a local file for that user as a last resort. + + // Check local file for that user as a last resort. if (file_exists) { return PAM_PERM_DENIED; } - // Otherwise, fall back on success to allow local users to log in. - return PAM_SUCCESS; + + // We can't confirm this is an OS Login user, ignore module. + return PAM_IGNORE; } - string email; + std::string email; if (!ParseJsonToEmail(response, &email) || email.empty()) { - return PAM_PERM_DENIED; + return PAM_AUTH_ERR; } url.str(""); @@ -101,28 +101,26 @@ chmod(users_filename.c_str(), S_IRUSR | S_IWUSR | S_IRGRP); } PAM_SYSLOG(pamh, LOG_INFO, - "Granting login permission for organization user %s.", + "Organization user %s has login permission.", user_name); - pam_result = PAM_SUCCESS; + return PAM_SUCCESS; } else { if (file_exists) { remove(users_filename.c_str()); } PAM_SYSLOG(pamh, LOG_INFO, - "Denying login permission for organization user %s.", + "Organization user %s does not have login permission.", user_name); - pam_result = PAM_PERM_DENIED; + return PAM_PERM_DENIED; } - return pam_result; } + PAM_EXTERN int pam_sm_setcred(pam_handle_t * pamh, int flags, int argc, - const char **argv) -{ + const char **argv) { return PAM_SUCCESS; } - PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags, int argc, const char **argv) { @@ -132,23 +130,23 @@ return PAM_PERM_DENIED; } - string str_user_name(user_name); + std::string str_user_name(user_name); if (!ValidateUserName(user_name)) { return PAM_PERM_DENIED; } - string response; + std::string response; if (!(GetUser(str_user_name, &response))) { return PAM_PERM_DENIED; } // System accounts begin with the prefix `sa_`. - string sa_prefix = "sa_"; + std::string sa_prefix = "sa_"; if (str_user_name.compare(0, sa_prefix.size(), sa_prefix) == 0) { return PAM_SUCCESS; } - string email; + std::string email; if (!ParseJsonToEmail(response, &email) || email.empty()) { return PAM_PERM_DENIED; } @@ -161,7 +159,7 @@ return PAM_PERM_DENIED; } - string status; + std::string status; if (!ParseJsonToKey(response, "status", &status)) { PAM_SYSLOG(pamh, LOG_ERR, "Failed to parse status from start session response"); @@ -172,7 +170,7 @@ return PAM_SUCCESS; // User is not two-factor enabled. } - string session_id; + std::string session_id; if (!ParseJsonToKey(response, "sessionId", &session_id)) { return PAM_PERM_DENIED; } @@ -184,7 +182,7 @@ return PAM_PERM_DENIED; } - std::map user_prompts; + std::map user_prompts; user_prompts[AUTHZEN] = "Google phone prompt"; user_prompts[TOTP] = "Security code from Google Authenticator application"; user_prompts[INTERNAL_TWO_FACTOR] = "Security code from security key"; diff -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/boto/tests/compute_auth_test.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/boto/tests/compute_auth_test.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/boto/tests/compute_auth_test.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/boto/tests/compute_auth_test.py 2019-05-21 20:40:07.000000000 +0000 @@ -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 -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/compat.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/compat.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/compat.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/compat.py 2019-05-21 20:40:07.000000000 +0000 @@ -19,17 +19,23 @@ import subprocess import sys -if sys.version_info >= (3, 6): +if sys.version_info >= (3, 7): import distro else: import platform as distro if 'freebsd' in sys.platform: - distribution = distro.version().split() + # Note: Do not use .version() method which is from either platform or distro. + # platform.version() and distro.version() return different values. + # platform.version() returns 'FreeBSD 11.2-RELEASE-p9.....'. + # distro.version() returns '11.2'. + distro_name = 'freebsd' + # distro_version is not used for FreeBSD later in this code. + distro_version = None else: distribution = distro.linux_distribution() -distro_name = distribution[0].lower() -distro_version = distribution[1].split('.')[0] + distro_name = distribution[0].lower() + distro_version = distribution[1].split('.')[0] distro_utils = None if 'centos' in distro_name and distro_version == '6': diff -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/constants.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/constants.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/constants.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/constants.py 2019-05-21 20:40:07.000000000 +0000 @@ -16,25 +16,34 @@ """A module for global constants.""" import platform +import sys OSLOGIN_CONTROL_SCRIPT = 'google_oslogin_control' OSLOGIN_NSS_CACHE_SCRIPT = 'google_oslogin_nss_cache' if platform.system() == 'FreeBSD': - LOCALBASE = '/usr/local' - BOTOCONFDIR = '/usr/local' - SYSCONFDIR = '/usr/local/etc' - LOCALSTATEDIR = '/var/spool' - OSLOGIN_NSS_CACHE = '/usr/local/etc/oslogin_passwd.cache' + BOTOCONFDIR = '/usr/local' + LOCALBASE = '/usr/local' + LOCALSTATEDIR = '/var/spool' + OSLOGIN_NSS_CACHE = '/usr/local/etc/oslogin_passwd.cache' + SYSCONFDIR = '/usr/local/etc' + SYSLOG_SOCKET = '/var/run/log' elif platform.system() == 'OpenBSD': - LOCALBASE = '/usr/local' - BOTOCONFDIR = '' - SYSCONFDIR = '/usr/local/etc' - LOCALSTATEDIR = '/var/spool' - OSLOGIN_NSS_CACHE = '/usr/local/etc/oslogin_passwd.cache' + BOTOCONFDIR = '' + LOCALBASE = '/usr/local' + LOCALSTATEDIR = '/var/spool' + OSLOGIN_NSS_CACHE = '/usr/local/etc/oslogin_passwd.cache' + SYSCONFDIR = '/usr/local/etc' + SYSLOG_SOCKET = '/dev/log' else: - LOCALBASE = '' - BOTOCONFDIR = '' - SYSCONFDIR = '/etc/default' - LOCALSTATEDIR = '/var' - OSLOGIN_NSS_CACHE = '/etc/oslogin_passwd.cache' + BOTOCONFDIR = '' + LOCALBASE = '' + LOCALSTATEDIR = '/var' + 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 -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_config.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_config.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_config.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_config.py 2019-05-21 20:40:07.000000000 +0000 @@ -78,7 +78,7 @@ '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 -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_setup.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_setup.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_setup.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/instance_setup/instance_setup.py 2019-05-21 20:40:07.000000000 +0000 @@ -28,9 +28,21 @@ 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 @@ 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 @@ 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 @@ 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 -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/instance_setup/tests/instance_setup_test.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/instance_setup/tests/instance_setup_test.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/instance_setup/tests/instance_setup_test.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/instance_setup/tests/instance_setup_test.py 2019-05-21 20:40:07.000000000 +0000 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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 -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/logger.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/logger.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/logger.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/logger.py 2019-05-21 20:40:07.000000000 +0000 @@ -15,6 +15,7 @@ """A library for logging text to SysLog and the serial console.""" +from google_compute_engine import constants from google_compute_engine.compat import logging @@ -46,7 +47,7 @@ if facility: # Create a handler for sending logs to SysLog. syslog_handler = logging.handlers.SysLogHandler( - address='/dev/log', facility=facility) + address=constants.SYSLOG_SOCKET, facility=facility) syslog_handler.setLevel(logging.INFO) syslog_handler.setFormatter(formatter) logger.addHandler(syslog_handler) diff -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_executor.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_executor.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_executor.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_executor.py 2019-05-21 20:40:07.000000000 +0000 @@ -19,8 +19,6 @@ import stat import subprocess -from google_compute_engine import constants - class ScriptExecutor(object): """A class for executing user provided metadata scripts.""" diff -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_retriever.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_retriever.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_retriever.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/script_retriever.py 2019-05-21 20:40:07.000000000 +0000 @@ -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 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 @@ 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 @@ 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 @@ 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 -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/tests/script_retriever_test.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/tests/script_retriever_test.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/tests/script_retriever_test.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/metadata_scripts/tests/script_retriever_test.py 2019-05-21 20:40:07.000000000 +0000 @@ -19,7 +19,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/tests/compat_test.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/tests/compat_test.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/google_compute_engine/tests/compat_test.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/google_compute_engine/tests/compat_test.py 2019-05-21 20:40:07.000000000 +0000 @@ -109,10 +109,8 @@ self.assertEqual( test_cases[distro], google_compute_engine.compat.distro_utils) - @mock.patch('google_compute_engine.compat.sys.platform', 'freebsd') - @mock.patch('google_compute_engine.compat.distro.version') - def testDistroCompatFreeBSD(self, mock_call): - mock_call.return_value = 'FreeBSD 11.1-RELEASE-p4 #0: Tue Nov 14 06:12:40' + @mock.patch('google_compute_engine.compat.sys.platform', 'freebsd11') + def testDistroCompatFreeBSD(self): reload_import(google_compute_engine.compat) self.assertEqual( google_compute_engine.distro_lib.freebsd_11.utils, diff -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/packaging/debian/changelog gce-compute-image-packages-20190521/packages/python-google-compute-engine/packaging/debian/changelog --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/packaging/debian/changelog 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/packaging/debian/changelog 2019-05-21 20:40:07.000000000 +0000 @@ -1,3 +1,18 @@ +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 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. + + -- Google Cloud Team Tue, 16 Apr 2019 12:00:00 -0700 + python-google-compute-engine (2.8.13-1) stable; urgency=low * Fix metadata script retrieval to support Python 3. diff -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/packaging/python3-google-compute-engine.spec gce-compute-image-packages-20190521/packages/python-google-compute-engine/packaging/python3-google-compute-engine.spec --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/packaging/python3-google-compute-engine.spec 1970-01-01 00:00:00.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/packaging/python3-google-compute-engine.spec 2019-05-21 20:40:07.000000000 +0000 @@ -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 -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/packaging/setup_deb.sh gce-compute-image-packages-20190521/packages/python-google-compute-engine/packaging/setup_deb.sh --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/packaging/setup_deb.sh 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/packaging/setup_deb.sh 2019-05-21 20:40:07.000000000 +0000 @@ -14,7 +14,7 @@ # limitations under the License. NAME="python-google-compute-engine" -VERSION="2.8.13" +VERSION="2.8.15" working_dir=${PWD} if [[ $(basename "$working_dir") != $NAME ]]; then diff -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/packaging/setup_rpm.sh gce-compute-image-packages-20190521/packages/python-google-compute-engine/packaging/setup_rpm.sh --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/packaging/setup_rpm.sh 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/packaging/setup_rpm.sh 2019-05-21 20:40:07.000000000 +0000 @@ -14,7 +14,7 @@ # limitations under the License. NAME="python-google-compute-engine" -VERSION="2.8.13" +VERSION="2.8.15" rpm_working_dir=/tmp/rpmpackage/${NAME}-${VERSION} working_dir=${PWD} @@ -23,12 +23,17 @@ 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 -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/README.md gce-compute-image-packages-20190521/packages/python-google-compute-engine/README.md --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/README.md 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/README.md 2019-05-21 20:40:07.000000000 +0000 @@ -28,8 +28,6 @@ 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 @@ 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. @@ -241,8 +239,7 @@ MetadataScripts | shutdown | `false` disables shutdown script execution. NetworkInterfaces | setup | `false` skips network interface setup. NetworkInterfaces | ip\_forwarding | `false` skips IP forwarding. -NetworkInterfaces | dhclient\_script | String path to a dhclient script used by dhclient. -NetworkInterfaces | dhcp\_command | String to execute to enable network interfaces. +NetworkInterfaces | dhcp\_command | String path for alternate dhcp executable used to enable network interfaces. Setting `network_enabled` to `false` will skip setting up host keys and the `boto` config in the guest. The setting may also prevent startup and shutdown diff -Nru gce-compute-image-packages-20190315/packages/python-google-compute-engine/setup.py gce-compute-image-packages-20190521/packages/python-google-compute-engine/setup.py --- gce-compute-image-packages-20190315/packages/python-google-compute-engine/setup.py 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/packages/python-google-compute-engine/setup.py 2019-05-21 20:40:07.000000000 +0000 @@ -20,8 +20,10 @@ 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 @@ 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': [ diff -Nru gce-compute-image-packages-20190315/README.md gce-compute-image-packages-20190521/README.md --- gce-compute-image-packages-20190315/README.md 2019-03-15 21:54:01.000000000 +0000 +++ gce-compute-image-packages-20190521/README.md 2019-05-21 20:40:07.000000000 +0000 @@ -43,10 +43,11 @@ 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 @@ ``` 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